One for students to study and summarize. If there is something wrong, please advise

cookie

The birth of

HTTP is a stateless protocol. Once the data exchange is complete, the connection between the client and server is closed and a new connection needs to be established to exchange data again.

To solve this problem, cookies appear

A cookie is introduced

Cookies are generated by the server and sent to the User-agent (usually the browser) to inform the browser to set cookies. The browser will automatically save cookies (in the form of key/value). The Cookie will also be automatically sent to the server when the same site is requested next time, that is, added to the request header.

In the browser side

The principle is code implementation

const http = require("http")
http.createServer((req, res) = > {
    // See if the cookie exists. If so, print the cookie
    console.log('cookie:', req.headers.cookie)
    / / set the cookie
    res.setHeader('Set-Cookie'.'cookie=abc; ')
    res.end('hello cookie!! ')
}).listen(3000)
Copy the code

The results show

Why twice?

The cookie was not found on the first request and was set

The second request, found a cookie, directly output

session

  1. Based on thecookieImplementation, stored on the server side
  2. There’s only one in therecookieIdOthers are stored on the server

Code is principle demonstration

// principle
const http = require("http")
const session = {} // Store cookies
http.createServer((req, res) = > {
    // Check that cookies exist
    console.log('cookie:', req.headers.cookie)
    const sessionKey = 'sid'
    const cookie = req.headers.cookie
    if (cookie && cookie.indexOf(sessionKey) > - 1) { // Prove that cookies exist
        res.end('Come Back ')
        // The shorthand is not necessarily universal
        const pattern = new RegExp(`${sessionKey}= (/ ^; +); ? \s*`)  // The regular expression object determines whether sid = XX, etc
        console.log(pattern)
        const sid = pattern.exec(cookie)[1] // Retrieves the value specified in the string. Returns the value found
        console.log('session:', sid, session, session[sid])
    } else {
        const sid = (Math.random() * 99999999).toFixed()
        / / set the cookie
        res.setHeader('Set-Cookie'.`${sessionKey}=${sid}; `)
        session[sid] = {name: 'oldWang'}
        res.end('Hello')
    }
    res.end('hello cookie!! ')
}).listen(3000)
Copy the code

Analysis of the

If there are no cookies in the browser, set a random SID, set a cookie, store the user’s information in the session (usually in the database), and return the result

On the second entry, if is used to determine the value.

Token

Use reasons

  1. The Session is insufficientThe server exists
  2. Is not flexible, (cookieExists only in browsers)

process

  1. The client requests login using the username and password
  2. The server receives a request to verify the user name and password
  3. After the authentication succeeds, the server issues a Token and sends the Token to the client
  4. After receiving the Token, the client can store it, such as in a Cookie or Local Storage
  5. Each time a client requests resources from the server, it must carry a Token signed by the server
  6. The server receives the request and verifies the Token in the request. If the verification succeeds, it returns the requested data to the client

Example realize

The front desk


      
<html lang="en">
<head>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <div><input v-model="username"/> <input v-model="password"/></div>
    <div>
        <button @click="login">landing</button>
        <button @click="logout">exit</button>
        <button @click="getUser" >Get the user</button>
    </div>
    <div>
        <button @click="logs=[]">Remove page</button>
    </div>  
    <ul>
        <li v-for="(log,idx) in logs" :key="idx"> {{ log }}</li>
    </ul>
</div>
<script>
    axios.defaults.baseURL = 'http://localhost:3000'
    axios.defaults.withCredentials = true
    axios.interceptors.request.use(config= > {
        const token = window.localStorage.getItem("token");
        if (token) {
            // Determine whether a token exists, and if so, add a token to each HTTP header
            // Bearer is a confirmed header of JWT
            config.headers.common["Authorization"] = "Bearer " + token;
        }
        return config;
    }, err => {
        return Promise.reject(err);
    });
    axios.interceptors.response.use(response= > {
        app.logs.push(JSON.stringify(response.data));
        return response;
    }, err => {
        app.logs.push(JSON.stringify(response.data));
        return Promise.reject(err);
    });
    var app = new Vue({
        el: "#app".data: {
            username: "admin".password: "admin".logs: []},methods: {
            login: async function () {
                const res = await axios.post("/users/login-token", {
                    username: this.username,
                    password: this.password
                });
                localStorage.setItem("token", res.data.token);
            }, logout: async function () {
                this.logs.push('Log out')
                localStorage.removeItem("token");
            }, getUser: async function () {
                await axios.get("/users/getUser-token"); }}});</script>
</body>
</html>
Copy the code

The background code

const Koa = require('koa')
const router = require('koa-router') ()/ / koa routing
const jwt = require("jsonwebtoken")
const jwtAuth = require("koa-jwt")
const secret = "it's a secret"
const cors = require('koa2-cors')
/ / https://www.jb51.net/article/135924.htm cross-domain reference
const bodyParser = require('koa-bodyparser') // Table is not supported, json is supported
const static = require('koa-static')
const app = new Koa();

app.keys = ['some secret'];
app.use(cors({credentials: true})) // Resolve cross-domain
app.use(static(__dirname + '/'));
app.use(bodyParser())
router.post("/users/login-token".async ctx => {
    const {body} = ctx.request;
    console.log(body)
    // Login logic, abbreviated
    / / set the session
    const userinfo = body.username;
    ctx.body = {
        message: "Login successful".user: userinfo,
        // Generate a token and return it to the client
        token: jwt.sign({
            data: userinfo,
            // Set the token expiration time in seconds after one hour
            exp: Math.floor(Date.now() / 1000) + 60 * 60
        }, secret)
    };
})

router.get("/users/getUser-token", jwtAuth({secret}), async ctx => {
    // The authentication passed, state.user
    console.log(ctx.state.user);
    / / get the session
    ctx.body = {message: "Data obtained successfully".userinfo: ctx.state.user.data};
});

app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000);

Copy the code

jsonwebtoken github