Implementing Token Authentication

Generate tokens using jsonWebToken

Github:github.com/auth0/node-… >

npm install jsonwebtoken
Copy the code

Use an egg – JWT

Making: < github.com/okoala/egg-…

The benefit of egg-JWT middleware is that tokens can be verified directly by keys

It encapsulates the logical code that validates the token

  • The JWT authentication middleware uses the JWT token to authenticate the caller. If the token is valid, thenctx.state.userJSON objects will be set (by default), which will be decoded for use by future middleware for authorization and access control.
  • Use egg-jwt to set up the interface that requires token verification to access. After successful verification, state information can be obtained from state in the context, and ctx.state.user obtains the user object
npm install egg-jwt
Copy the code

config/plugin.js

// egg-jwt
exports.jwt = {
    enable: true.package: "egg-jwt"
};
Copy the code

config/config.default.js

module.exports = appInfo= > {
  const config = exports = {};
  config.middleware = ['errorHandle'];  
    config.jwt = {
        secret: 'secret'./ / key
       ignore: [/^\/user\/login/].// Which requests do not require authentication
    }

       return {
        ...config
    };
};
Copy the code

app/router.js

 module.exports = app= > {
    const { router, controller } = app;
     // Use egg-jWT middleware for authorization, and the next middleware is executed only if authorization succeeds
    router.get('/user/authorization', app.jwt, controller.user.auth);  / / token authorization
   };
Copy the code

app/middleware/error_handle.js

  • Unified error handling

If JWT has an expiration (exp), it will be checked.

Handle token authentication exceptions, such as token expiration or token error

/** * @description: Unified error handling * @code 401 Unauthorized 500: server internal error 422: Status code indicates that the request is well-formed, but cannot be responded to due to semantic error. * @return: */

module.exports = (options, app) = > {
    return async function(ctx, next) {
        try {
            await next()
        } catch (err) {

            // All exceptions raise an error event on the app, and the Egg records an error log
            ctx.app.emit('error', err, ctx);
            const status = err.status || 500;
            // The details of the 500 error in production are not returned to the client because they may contain sensitive information
            const error = status === 500 && ctx.app.config.env === 'prod' ?
                'Internal Server Error' :
                err.message;
            if (status === 401) {
                // Custom JWT error handling
                ctx.body = {
                    code: 401.// Token expires or is incorrect
                    msg: "token error"}}else if (status === 422) {
                //422: The request is well formed, but contains semantic errors
                ctx.body.detail = err.errors;
            } else {
                // Read each property from the error object and set it into the responsectx.body = { error }; ctx.status = status; }}}}Copy the code

app/extend/helper.js

  • The Helper function is used to provide some useful utility functions, easy to call
const jwt = require('jsonwebtoken')
module.exports = {
    / / Token is generated
    getToken(payload = {}, secret) {
        return jwt.sign(payload, secret, { expiresIn: '1h'}); }}Copy the code

app/controller/user.js

'use strict';
const Controller = require('egg').Controller;
class UserController extends Controller {
    async login() {
            const { ctx, app } = this;
            const { username, password } = ctx.params;
            // const secret = app.config.secret;
            const secret = app.config.jwt.secret
            const token = ctx.helper.getToken({ username }, secret);
            / / simulation
            if (username === '123' && password === '123') {
                ctx.body = {
                    code: 200.message: 'Login successful',
                    token,
                }
            } else if(username ! = ='123') {
                ctx.body = {
                    code: 200.message: 'Username does not exist',}}else if (username === '123', password ! = ='123') {
                ctx.body = {
                    code: 200.message: 'Password error',}}}/ / token authorization
    async auth() {
            const { ctx, app } = this;
            const { username } = ctx.state.user
            const secret = app.config.jwt.secret
            const token = ctx.helper.getToken({ username }, secret);
            ctx.body = {
                code: 200,
                token
            }

        }
  
    
}
module.exports = UserController;
Copy the code