What is the JWT

JWT — Json Web Token JWT — Json Web Token is an open jSON-based standard implemented to transfer declarations between network application environments. It can implement stateless and distributed Authorization of Web applications.

Why do YOU need JWT

The back-end interfaces are deployed in a distributed environment

Traditional session authentication

As we know, the HTTP protocol itself is a stateless protocol, which means that if the user to our application provides a user name and password for user authentication, so the next time a request, the user will once again for user authentication, because based on HTTP protocol, we don’t know is which user requests, So in order for our application to be able to identify which user is making the request, we can only store a copy of the user’s login information on the server, and this login information is passed to the browser in response, telling it to save as a cookie, so that it can be sent to our application in the next request. So our application can identify the user from whom the request is coming, which is traditional session-based authentication. However, session-based authentication makes it difficult to expand the application itself. With the increase of different client users, the independent server can no longer bear more users, and the problems of session-based authentication applications will be exposed.

  • Cookies cannot cross domains
    • Front-end: not on a dedicated server, but given a CDN or domain name when accessed
    • Backend: Deployed on a dedicated server, using a domain name
  • Multi-terminal PC, mobile phone, webApp, App, small program
    • App and applets do not support cookies and sessions
  • Sessions cannot be shared in distributed environments
    • Session works on the server and records user information on the server
    • You need to find a way to share user information across multiple servers

Token-based authentication mechanism

Similar to HTTP, token-based authentication is stateless and does not need to retain user authentication information or session information on the server. This means that token-based applications do not need to consider which server users log in to, which facilitates application expansion. Token => string => stored in client (localstorage sessionstorage, localstorage) => send request to manually carry token flow looks like this:

  1. The user requests the server using a username and password
  2. The server authenticates the user’s information. The server sends a token to the user after authentication
  3. The client stores the token and supplies it with each request. The server validates the token and returns data
  4. This token must be passed to the server on every request, it should be stored in the header of the request, and the server should support THE CORS(Cross-source resource Sharing) policy, which is usually done on the serverAccess-Control-Allow-Origin:*.

In other words, compared with traditional cookie-based session, token-based JWT has the following advantages:

  1. Cookies do not allow out-of-domain access, which does not exist for the Token mechanism, provided that the transmitted user authentication information is transmitted through HTTP headers.
  2. Stateless (also called server extensible line): The Token mechanism does not need to store session information on the server, because the Token itself contains information about all login users. The status information only needs to be stored in the cookie or local media of the client.
  3. More suitable for CDN: you can request all the data (javascript, HTML, images, etc.) from your server via content distribution network, as long as your server provides the API.
  4. Decoupling: There is no need to bind to a specific authentication scheme. Tokens can be generated anywhere, as long as you can make Token generation calls when your API is called.
  5. More suitable for mobile applications: When your client is a native platform (iOS, Android, Windows 8, etc.), cookies are not supported (you need to use Cookie containers for processing), then Token authentication is much easier.
  6. CSRF: Because you no longer rely on cookies, you don’t need to worry about defending against CSRF (cross-site request forgery).
  7. Performance: A network round-trip time (query session information from the database) is always much more time-consuming than a Token verification and resolution of HMACSHA256 calculation.
  8. No special handling for the login page: If you are functional testing with the Protractor, there is no special handling for the login page.
  9. Standardisation based: Your API can use standardised JSON Web tokens (JWT). The standard already exists in several back-end libraries (.NET, Ruby, Java,Python, PHP) and is supported by several companies (e.g. Firebase,Google, Microsoft).

Json Web Token (JWT)

JWT is used for identity authentication and can be used to pass user insensitive data between clients and servers

JWT composition:

The payload is the payload, and the Signature is the payload.

How do I use JWT

  1. The user account and password are verified successfully. The token is generated and sent to the client and saved
  2. Each Ajax request from the client is sent to the server with a token for verification
    1. Get query string
    2. The header request header
    3. Body request body
  3. Server validation Interface, in need to the authentication token validation, by continuing to return to the business logic results | not by returning authentication failure

JWT authentication operation

Environment: Node. Js Vue2.0 project Egg. Js plug-in: egg-jwt:www.npmjs.com/package/egg… Egg-validate-plus-next:www.npmjs.com/package/egg…

Installing a plug-in

Enter the following commands on the terminal to install the plug-in:

npm i egg-validate-plus-next

npm i egg-jwt --save
Copy the code

An egg – validate – plus – next configuration

Open the plug-in

// config/plugin.js

module.exports = {
  The validation rule plug-in is enabled
  validatePlusNext: {
    enable: true.package: 'egg-validate-plus-next',}}Copy the code

Configure the plug-in

// config/config.default.js

const userConfig = {
  // Validate rule plug-in configuration
  validatePlusNext: {
    resolveError(ctx, errors) {
      if (errors.length) {
        ctx.type = 'json';
        ctx.status = 200; // Changes the status code of the HTTP response
        ctx.body = {
          code: 404.error: errors,
          msg: 'Parameter error'}; }}},}Copy the code

Use plug-ins to define validation rules for login modules either in the APP /validate directory or directly on the controller

// app/controller/login.js

const rules = {
username: { type: 'string'.required: true.max: 10.message: 'User name cannot be empty' },
password: { type: 'string'.required: true.max: 10.message: 'Password cannot be empty'}};const valid = await this.ctx.validate(rules, this.ctx.request.body, 'rule');
if(! valid)return;
Copy the code

An egg – JWT configuration

// /config/plugin.js

module.exports = {
  jwt: {
    enable: true.package: 'egg-jwt',}}Copy the code
// config/config.default.js

const userConfig = {
  jwt: {
    secret: 'jiaju2022'.// Signature Indicates the Signature key}},Copy the code

Registered routing

// app/router.js

router.post('login'.'/api/login', controller.login.checkLogin); / / login
Copy the code

Register controller

// app/controller/login.js

async checkLogin() {
// Content validation
const rules = {
  username: { type: 'string'.required: true.max: 10.message: 'User name cannot be empty' },
  password: { type: 'string'.required: true.max: 10.message: 'Password cannot be empty'}};const valid = await this.ctx.validate(rules, this.ctx.request.body, 'rule');
if(! valid)return;
// Call the service for commit to background validation
const token = await this.ctx.service.login.checkLogin(this.ctx.request.body);
this.ctx.body = {
  code: 200.msg: 'Login successful'.data: token,
};
}
Copy the code

Steps:

  1. The console submits the username and password via POST,this.ctx.validateInvoke validation rules for data validation
  2. If the verification fails, a message in the verification rule is displayed
  3. If the authentication passes, the controller will continue to perform the operation. The controller will invoke the service and transfer the user name, password and other information submitted by the foreground to the service
  4. Passes when the service respondsthis.ctx.bodyReturns the result

service

// app/service/login.js

async checkLogin(data) {
const { username, password } = data;
const user = await this.ctx.model.Admin.findOne(data, {
  where: {
    username,
  },
});
if (username) {
  if (user.password === this.ctx.helper.pwd(password)) {
    const token = this.app.jwt.sign({ username }, this.app.config.jwt.secret);
    return { token };
  } else if(user.password ! = =this.ctx.helper.pwd(password)) {
    this.ctx.throw(200.'Password error'); }}else {
  this.ctx.throw(200.'Username does not exist'); }}Copy the code

Steps:

  1. When a parameter is received from the controller, it passes throughthis.ctx.model.Admin.findOne()Method calls the database and sets the query condition to the username passed by the foreground.
  2. If the user name exists, the system checks whether the password passed by the foreground is consistent with the password found in the background database. If the password is inconsistent, the system prompts that the user name does not exist
  3. If the passwords are the same, set the token and return. Otherwise, the password is incorrect