> For the complete documentation index, see [llms.txt](https://jen-hsuan-hsieh.gitbook.io/asp-net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jen-hsuan-hsieh.gitbook.io/asp-net/chapter3rest-api-design-development-and-management/34rest-api-security/343securing-api-with-tokens-and-jwt.md).

# 3.4.3.Securing API with Tokens & JWT

* Token based authentication
  * 1.Client向API server索取token
    * 如果body中的name, password符合則用secret加密新的payload (Base64)後形成的token, 回傳給Client
    * 如果body中的name, password不符合則回401
  * 2.Client將token放到header, 向API server索取資料
    * 如果header中的token是undefined, 則回401
    * 如果header中的token在server的記憶體中不存在則視為Unauthorized, 回401&#x20;
    * 如果header中的token無法被secret decode, 或是decode後的expired time超過時間則視為invalid, 從server的記憶體中將token刪除, 回401   &#x20;
    * 否則將token存放在server的記憶體中, 回200&#x20;

      ![](https://163116165-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M4M0G7tIs4o9F9vSrao%2F-M4M0IVB0ax0vs2ocz_r%2F-M4M0XLDYbW66JQ4Qd6Q%2F%E6%9C%AA%E5%91%BD%E5%90%8D23319.jpg?generation=1586302966051878\&alt=media)
* Token
  * **Token are encoded strings used for authentication**
    * hashing or private key for encryption
  * Eliminates the need of sessions on the API
    * HTTP header
    * Query parameters
    * Request body&#x20;
  * Issuer can control the validity&#x20;
    * Expiry
    * Revocation
* [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519)
  * 由三個部分組成
    * 1.以Base64加密Header後的字串
    * 2.以Base64加密Payload後的字串
    * 3.Signature字串
* Header
  * Type
    * "JWT"
  * Algorithm
    * HS256, HMAC
  * e.g.,

    ```
    {
      type: "JWT",
      alg" "HMAC"
    }
    ```
* [Payload (claims)](https://www.iana.org/assignments/jwt/jwt.xhtml)
  * Registered   &#x20;
    * iss
    * exp
    * nbf
  * Public
    * name
    * Email
    * phone\_number
  * Private
    * agree upon by consumer & provider
  * e.g.,

    ```
    {
      exp: "288828888",
      iss: "Sam",
      name: "John"
    }
    ```
* Signature
  * (以Base64加密Header後的字串 + "." + 以Base64加密Payload後的字串)再以secret hash過的字串
* Sample code
  * [Visual studio code](https://code.visualstudio.com/docs/?dv=win)
  * [node.js](https://nodejs.org/en/)
  * [source code from github](https://github.com/acloudfan/REST-API-security)
    * 1.clone repository

      ```
      git clone https://github.com/acloudfan/REST-API-security.git
      cd REST-API-COURSE/
      npm install
      ```
* 程式碼解析
  * 使用套件: [jwt-simple](https://github.com/hokaccha/node-jwt-simple)
  * 流程
    * Client向API server索取token
    * 如果body中的name, password符合則用secret加密新的payload後形成的token, 回傳給Client
    * 如果body中的name, password不符合則回401
  * Client將token放到header, 向API server索取資料
    * 如果header中的token是undefined, 則回401
    * 如果header中的token在Server端不存在則視為Unauthorized, 回401&#x20;
    * 如果header中的token無法被secret decode, 或是decode後的expired time超過時間則視為invalid, 回401   &#x20;
    * 否則回200&#x20;

      ![](https://163116165-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M4M0G7tIs4o9F9vSrao%2F-M4M0IVB0ax0vs2ocz_r%2F-M4M0XLFrzBFQlnBLp1n%2F%E6%9C%AA%E5%91%BD2323%E5%90%8D.jpg?generation=1586302965915937\&alt=media)
* 將auth function作為middleware function, 放在middleware callback處

```
// JWT Token Authentication
// Part of the course on "REST API Design Development & Management"
// http://www.acloudfan.com

var     express = require('express')
var     bodyParser = require('body-parser')
var     jwtAuth = require(__dirname + '/tokens/jwtauth')
var     jwtValidate = require(__dirname + '/tokens/validator')

// Express app setup
var app = express();
app.use(bodyParser.json())
var router = express.Router();

// This is the passport middlewae function tha get called first
var  auth = jwtAuth.auth
router.post('/token',auth,function(req, res){
    res.send('token');
});

auth = jwtValidate.auth
router.get('/private',auth,function(req,res){
    res.send('Access granted to private resource!!!')
});

app.use(router);

app.listen(3000);

console.log('Listening on 3000')
```
