Angular the jwt token authentication
demo https://gitee.com/powersky/jwt
Introduction
Web token json (the JWT), is a statement in order to pass between the network application execution environment based on JSON open standards ((RFC 7519). The token is designed to be compact and safe, especially for single-distributed sites sign-on (SSO) scenario .JWT statements are typically used to provide and service providers transfer between the user identity is authenticated identity information in order to obtain resources from the server, you can also add some extra other business logic that must be statement information, the token can be directly used for authentication may be encrypted.
origin
In speaking JWT before be sure to talk about based on token and session different.
Traditional session authentication
http protocol itself is a stateless protocol, meaning that if the user provides a user name and password to our application for user authentication, then the next time request, the user should again for user authentication for the job, because, according to http agreement, we can not know which user request is sent, so in order to make our application can identify which user request is issued, we can only store information about a user is logged on the server, this login information is passed in response to to the browser, tell it to save the cookie , so that next time the application is sent to our request, so that our application will be able to identify which user requests from, and this is based on the traditional session authentication.
But this based session authentication so that the application itself is difficult to be expanded, with the increase of users of different clients, independent of the server is unable to carry more users, but this time based session issue certification applications will be exposed.
working principle
When the client user name, password request server and pass the authentication, server generates authentication-related session data and stored in memory or memory database. And corresponding sesssion_id
return to the Client , Client will save session_id
(under the signature can be encrypted to prevent tampering) in the cookie . After client all requests will be included with this session_id
(after all, the default cookie will pass server), to determine the server corresponding to the presence or absence of session data and to verify the login status and have what privileges, if by verifying respect of Why Why, otherwise, re-register.
The front exit, then to clear the cookie . The rear end of the front end of compulsory re-certification or modification, then to clear the session .
Advantages and disadvantages
Advantages :
- Compared JWT, the biggest advantage is that you can take the initiative to clear the session.
- session saved on the server side, they are relatively safe.
- Combine cookie use, more flexible, better compatibility.
Drawbacks :
-
Each user authentication after our application, our application on the server must do a record, to facilitate the identification of the user's next request, general session are stored in memory, and with the increase of the authenticated user, the cost of the server will be significantly increased.
-
After user authentication, the server doing the authentication record, if authenticated records are stored in memory, then this means that next time the user requests also have to request resources on this server, so as to get the authorization, so distributed on the application, the corresponding limits the ability of the load balancer. This also means that limits the scalability of applications.
In a distributed deployment, need to do more machines to share session mechanism, the session method can be stored in the database or in redis
-
Easy to CSRF, because it is based on the cookie to identify the user, if the cookie is intercepted, the user could be vulnerable to cross-site request forgery attacks.
-
In the inter-scene cookie + session was not good
Difference session, cookie, sessionStorage, localstorage of
session:
The main store on the server side, relatively safe.
cookie:
Can set the effective time, the default is to close the browser after the failure, the main storage of the client, and not very secure, store size is about 4kb.
sessionStorage:
It is only valid in the current session, close the browser page or after removal.
localstorage:
Unless cleared, otherwise permanent preservation.
JWT token-based authentication mechanisms
JWT essentially of "." Separated by three parts, namely the head , a payload and signature . A simple JWT example, as follows:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySUQiOjEsImlhdCI6MTU4MTMyMjE4MCwiZXhwIjoxNTgxMzI5MzgwfQ.6PVma3dLCbiXYgBJld5McFJ-q-QydCY7YVtrKPBsRi8
This part of the string is actually composed of three parts, the focus point of use of code division, the JWT representing in: Header , Payload , the Signature .
Header
JWT the Header typically comprises two fields, namely: Typ (type) and ALG (algorithm).
- typ: token type, there is fixed to the JWT .
- alg: encryption algorithm, commonly used directly
HMAC
SHA256
.
Complete head the following statement:
{
'typ': 'JWT',
'alg': 'HS256'
}
Then the head base64-encryption (the encrypted can be decrypted symmetric), constitutes the first portion.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Playload
Load is where to store valid information, valid information which contains the following three parts:
- Standard registration statement
- Public Statement
- Private statement
Standard registration statement
- ISS : jwt issuer
- Sub : JWT for the user
- AUD : the receiving side jwt
- exp : jwt expiration time, the expiration date must be greater than the issue of time.
- NBF : What time is defined before the JWT are not available.
- IAT : jwt the issue of time
- the JTI : jwt unique identity, is mainly used as a one-time token, in order to avoid a replay attack.
Timestamp is generally used unix timestamp indicates.
Public Statement
Public declarations can add any information, general information about the user to add the necessary information or other business needs, but does not recommend adding sensitive information, because the part of the client can be decrypted.
Private statement
Private statement is a statement providers and consumers as common definition, is generally not recommended to store sensitive information, because base64 is decrypted symmetric, meaning that some of the information may be classified as plaintext.
Define a simple payload , as follows:
{
userID: '1',
exp: '1581329380',
iat: '1581322180'
}
Then subjected base64 encryption obtain JWT second portion.
eyJ1c2VySUQiOjEsImlhdCI6MTU4MTMyMjE4MCwiZXhwIjoxNTgxMzI5MzgwfQ
Online conversion tools base64 address .
Signature
JWT The third part is a visa information, this visa information consists of three parts:
- header (after base64 encrypted)
- payload (encrypted after base64)
- secret
This part needs base64 encrypted header and base64 encrypted payload using String connection is provided, then header for encryption and declared secret combination of encryption, and then constitutes JWT third portion.
E.g:
// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
var signature = HMACSHA256(encodedString, 'secret');
secret is stored on the server side, JWT issued is generated on the server side, secret is used for JWT issued and JWT verification, so it is your server's private key, should not be revealed to any scene. Once the client has learned the Secret , it means that the client can be self-signed JWT , then your program will probably hire attacks.
Advantages and disadvantages
advantage:
- Because of the versatility of json, so JWT can be cross-language support, like JAVA, JavaScript, NodeJS, PHP and many other languages can be used.
- Because of the payload section, so you can store some JWT other business logic necessary for non-sensitive information in itself.
- Ease of transport, JWT configuration is very simple, small occupied bytes, so it is very easy to transport.
- It does not save session information on the server, so it is easy to extend applications.
Drawbacks:
- The need to renew the token design problem
- Need to design the user exits the token is still valid issues
- After the password change issues token is still valid
- There are a lot of small problems, but I think it is more good than harm
How to apply
It is generally added in advance in the request Authorization
, and add the Bearer
label:
fetch('api/user/1', {
headers: {
'Authorization': 'Bearer ' + token
}
})
Works as:
Angular used to authenticate JWT
Here TODO cases to use a demonstration.
API Design
/auth
POST submit a user nameusername
and passwordpassword
to login authentication, returns JWT string./todos
GET returns the to-do list./todos/{id}
GET returns the specified backlog./users
GET returns a list of users.
Brief program operation flow
First program has a login screen, the user needs to input user and password. When the form is submitted, it transmits the data to the front end of the rear end of the /auth
path. Take appropriate back-end query the user for verification, verification after successful return token string.
Back-end data declarations
// 定义用户
const USERS = [
{ id: 1, username: 'vincent', password: '123456'},
{ id: 2, username: 'bob', password: '123456'},
{ id: 3, username: 'peter', password: '123456'},
];
// 创建TODO列表,json格式
const TODOS = [
{ id: 1, userId: 1, name: "Play LOL", completed: false },
{ id: 2, userId: 1, name: "Do homework", completed: true },
{ id: 3, userId: 2, name: "Play basketball", completed: false },
{ id: 4, userId: 3, name: "Finish Angular JWT", completed: false },
];
Remember password can not be placed payload in, because it is not safe.
The back-end code implementation
-
Import library needed
const _ = require('lodash'); const express = require('express') const bodyParser = require('body-parser'); const jwt = require('jsonwebtoken'); const expressJwt = require('express-jwt');
-
Defined Functions
// 获取用户相关的所有Todo事项函数 function getTodos(userID) { var todos = _.filter(TODOS, ['userId', userID]); return todos; } // 获取指定id的todo事项 function getTodo(todoID) { var todo = _.find(TODOS, (todo) => { return todo.id == todoID; }) return todo; } // 获取所有用户 function getUsers() { let users = Array(USERS.length); for (let i = 0; i < USERS.length; i++) { users[i] = {id: USERS[i].id, username: USERS[i].username}; } return users; }
-
Use
expressJwt
generate tokentodo-shared-secret
Secret key is a string, that attention must be stored in the backend.
Specific code can come to https://gitee.com/powersky/jwt here. -
Implement other API
Front-end code implementation
The front end is divided into the following sections:
Services :
user service
Used to obtain user datatodo service
For acquiring data todoauth service
Token used to authenticate users to accessauth guard
For guarding the route, the route can be determined whether or not Skip
Components :
user list
User interface displaytodo list
User interface display todo todologin
User login interface
In order to show below.
-
user.service.ts
-
todo.service.ts
-
auth.service.ts
-
auth.guard.ts
-
UserListComponent
withhtml
-
TodoListComponent
withhtml
-
LoginComponent
withhtml
-
AppComponent
withhtml
-
AppRoutingModule
To be able to use a proxy need to add a configuration file:
proxy.conf.json
{
"/api/*": {
"target": "http://localhost:4000",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
}
}
Then package.json
added:
"name": "jwt",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve --proxy-config proxy.conf.json",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
Then execute the following command-line command to turn the front end:
npm start
Execute the following command to start the back-end:
node server/app.js
This this case is over.