Skip to content

jwt #106

Description

@uniquejava

What is a JSON Web Token?

没事就读读: What is a JSON Web Token?

JWT规范: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html

0 _tckw18m85-50ofn

JWT分三部分 header.payload.signature

header: {typ: ‘JWT’, alg: ‘HS256’}
payload: {userId: 2, admin: true}
signature: secret(header+payload)

其中header和payload是给浏览器用的, 仅是base64 encoded, (所以不要保存敏感信息)
最后的signature是给server用的, 是用服务端secret加密过的header+payload信息.

header和payload可以直接在jwt.io这个网站上显示出来, 如下图:

express-passport-json-web-token

JWT的传输方式

一共有三种, 分别是http header, http body 和 http url(query parameter)

1. Authorization Request Header Field

先了解一下Authorization的格式

W3C HTTP1.0规范中最早引入了如下风格的Authorization:

Authorization: <type> <credentials>

这里有解释为什么要这么定义, 简而言之, server端可能同时支持多种方式的authorization type.

如果type为Bearer那么server端有可能是实现了OAuth2(Bearer, 翻译: 持有者.)

但是这个Bearer含义最终是由你的server决定, 这里的JWT按照业内的通用做法放在Bearer后面完全可行.

     GET /resource HTTP/1.1
     Host: server.example.com
     Authorization: Bearer mF_9.B5f-4.1JqM

2. Form-Encoded Body Parameter

     POST /resource HTTP/1.1
     Host: server.example.com
     Content-Type: application/x-www-form-urlencoded

     access_token=mF_9.B5f-4.1JqM

3. URI Query Parameter

     GET /resource?access_token=mF_9.B5f-4.1JqM HTTP/1.1
     Host: server.example.com

4. 而server端响应token的格式如下:

     HTTP/1.1 200 OK
     Content-Type: application/json;charset=UTF-8
     Cache-Control: no-store
     Pragma: no-cache

     {
       "access_token":"mF_9.B5f-4.1JqM",
       "token_type":"Bearer",
       "expires_in":3600,
       "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"
     }

node jwt Tutorial 1 (仅做参考)

Make an API with Node.JS, MongoDB, and JWT Authentication

$ mkdir api-jwt && cd $_
$ npm init -y
$ npm i -S express body-parser mongoose mongoose-paginate kerberos cors morgan bcryptjs moment jwt-simple

这篇的作者写的代码真是漂亮, 知识点:

  1. 如何强制使用https (以及为什么jwt要配合https来使用)
  2. Mongoose分页
  3. 分离受保护和不受保护的routes.
  4. app/routes/controllers代码分层
  5. 如何用curl来测试api.
// 4. Force https in production
if (app.get('env') === 'production') {
  app.use(function(req, res, next) {
    var protocol = req.get('x-forwarded-proto');
    protocol == 'https' ? next() : res.redirect('https://' + req.hostname + req.url);
  });
}

node jwt Tutorial 2 (用得最多)

Simple Authentication in Node/Express using JWT (JSON Web Tokens)
这篇只通过两段代码演示了如何使用jwt. 我直接拷贝过来吧..

npm install jsonwebtokens

服务端生成JWT

var User = require('./userModel');
var jwt = require('jsonwebtokens');
var newUser = function (req, res){
  User.findOne({where:{ username: req.body.username }})
    .then(function (user) {
      if(!user){
        User.create({ 
          username: req.body.username, 
          password: req.body.password, 
          email: req.body.email 
        })
        .then(function(user){
              var myToken = jwt.sign({ user: user.id },
                                      'secret',
                                     { expiresIn: 24 * 60 * 60 });
              res.send(200, {'token': myToken,
                             'userId':    user.id,
                             'username': user.username });
        });
      } else {
        res.status(404).json('Username already exist!');
      }
    })
    .catch(function (err) {
      res.send('Error creating user: ', err.message);
    });
};

服务端解密JWT

var authorize = function(req, res, next) {
 var token = req.body.token || req.headers[‘x-access-token’];
  if (token) {
   jwt.verify(token, 'secret', function(err, decoded) {
      if (err) {
         console.error(‘JWT Verification Error’, err);
         return res.status(403).send(err);
      } else {
         req.decoded = decoded;
         return next();
      }
   });
  } else {
   res.status(403).send(‘Token not provided’);
   }
}

Cyper in Action

最终我选择了"jsonwebtoken": "^7.4.1",

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions