Nodejs 7. Identity authentication

Zero, article directory

Nodejs 7. Identity authentication

1. Web development model

(1) Current mainstream Web development models
  • Based on the traditional web development model of 服务端渲染
  • New Web development model based on前后端分离
(2) Server-side rendering Web development model
  • The HTML page sent by the server to the client is dynamically generated by concatenating strings on the server.
  • The client does not need to use technologies such as Ajax to additionally request page data.
(3) Advantages and disadvantages of server-side rendering
  • advantage
    • 前端耗时少: Because the server side is responsible for dynamically generating HTML content, the browser only needs to render the page directly.
    • 有利于SEO: Because the server responds to the complete HTML page content, it is easier for crawlers to crawl and obtain information, which is more conducive to SEO.
  • shortcoming
    • 占用服务器端资源: That is, the server completes the splicing of HTML page content. If there are many requests, it will put a certain amount of access pressure on the server.
    • 不利于前后端分离,开发效率低: If server-side rendering is used, 无法进行分工合作, especially for 前端复杂度高 projects, is not conducive to efficient project development.
(4) Web development model with front-end and back-end separation
  • The development model that separates the front and back ends,依赖于 Ajax 技术的广泛应用.
  • The Web development model that separates the front and back ends is the development model of后端只负责提供 API 接口,前端使用 Ajax 调用接口.
(5) Advantages and disadvantages of front-end and back-end separation
  • advantage

    • 开发体验好: The front-end focuses on the development of UI pages, and the back-end focuses on the development of APIs, and the front-end has more options.
    • 用户体验好: The extensive application of Ajax technology has greatly improved the user experience and can easily achieve partial refresh of the page.
    • 减轻了服务器端的渲染压力: Because the page is ultimately generated in each user's browser.
  • shortcoming

    • 不利于 SEO: Because the complete HTML page needs to be dynamically spliced ​​on the client, the crawler cannot crawl the effective information of the page. (Solution: Using the SSR (server side render) technology of front-end frameworks such as Vue and React can solve SEO problems very well!)
(6) How to choose a Web development model
  • 不谈业务场景而盲目选择使用何种开发模式都是耍流氓
  • For example, if an enterprise-level website’s main function is display without complex interactions, and requires good SEO, then we need to use server-side rendering;
  • For similar back-end management projects, which are highly interactive and do not need to consider SEO, you can use a development model that separates the front and back ends.
  • The specific development model to be used is not absolute. In order to同时兼顾了首页的渲染速度和前后端分离的开发效率, some websites adopt a development model of first-screen server-side rendering + front-end and back-end separation for other pages.

2. Identity authentication

(1) What is identity authentication?
  • 身份认证 (Authentication), also known as "identity verification" and "authentication", refers to 通过一定的手段,完成对用户身份的确认.
  • In Web development, user identity authentication is also involved, such as: 手机验证码登录、邮箱密码登录、二维码登录 of major websites, etc.
(2) Why identity authentication is needed
  • The purpose of identity authentication is for确认当前所声称为某种身份的用户,确实是所声称的用户. For example, if you go to the courier to pick up the express delivery, how do you prove that the express delivery is yours.
  • In the development of Internet projects, how to authenticate users' identities is an issue worthy of in-depth discussion. For example, how can we ensure that the website will not mistakenly display "Jack Ma's deposit amount" to "Ma Huateng's account".
(3) Identity authentication under different development modes
  • 服务端渲染Recommended UseSession 认证机制
  • 前后端分离Recommended UseJWT 认证机制

3. Session authentication mechanism

(1) Stateless nature of HTTP protocol
  • The stateless nature of the HTTP protocol refers to the client's 每次 HTTP 请求都是独立的. There is no direct relationship between multiple consecutive requests, 服务器不会主动保留每次 HTTP 请求的状态.
(2) How to break through the stateless limitations of HTTP
  • For supermarkets, in order to facilitate the cashier to give discounts to VIP users during settlement, the supermarket can issue 会员卡 to each VIP user.
  • The technical term in web development is Cookie.
(3) What are cookies?
  • Cookie is存储在用户浏览器中的一段不超过 4 KB 的字符串. It consists of one 名称(Name)、一个值(Value) and several other 有效期、安全性、使用范围的可选属性 for control cookies.
  • 不同域名下的 Cookie 各自独立, whenever the client initiates a request, 自动 will 当前域名下 all 未过期的 Cookie together< a i=4>. 发送到服务器
  • Several major characteristics of cookies:
    • auto delivery
    • Domain name independent
    • Expiration time
    • 4KB limit
(4) The role of cookies in identity authentication
  • When the client requests the server for the first time, the server sends a to the client through 响应头的形式, and the client will automatically . 身份认证的 Cookie将 Cookie 保存在浏览器中
  • Subsequently, when the client browser每次请求服务器的时候, the browser will自动pass the identity authentication related informationCookie through 请求头的形式Send it to the server, and the server can验明客户端的身份.

image-20230614170002689

(5) Cookies are not secure
  • Since Cookie 是存储在浏览器, and 浏览器也提供了读写 Cookie 的 API, therefore Cookie 很容易被伪造, is not safe.
  • It is not recommended that the server sends important private data to the browser in the form of cookies. For example, the user’s identity information, password, etc.
(6) Improve the security of identity authentication
  • In order防止客户伪造会员卡, the cashier can do this at the cash register after getting the membership card presented by the customer刷卡认证. Only membership cards confirmed by the cash register to exist can be used normally.
  • This "会员卡 + 刷卡认证" design concept is the essence of Session 认证机制.
(7) Working principle of Session

image-20230614170546244

4. Use Session authentication in Express

(1) Install express-session middleware
  • In the Express project, you only need to install the express-session middleware to use Session authentication in the project:
npm install express-session
(2) Configure express-session middleware
  • After the express-session middleware is successfully installed, you need to register the session middleware through app.use(). The sample code is as follows:
// 导入 session 中间件
const session = require('express-session')

// 配置 session 中间件
app.use(
    session({
    
    
        secret: 'keytest', //secret属性值可以是任意字符串
        resave: false,
        saveUninitialized: true,
    })
)
(3) Store data in session
  • After the express-session middleware is successfully configured, you can access and use the session object through req.session to store the user's key information:
app.post('/api/login', (req, res) => {
    
    
    // 判断用户提交的登录信息是否正确
    if (req.body.username !== 'admin' || req.body.password !== '000000') {
    
    
        return res.send({
    
     status: 1, msg: '登录失败' })
    }
    
    // 注意:只有成功配置了 express-session 这个中间件之后,才能够通过 req 点出来 session 这个属性
    req.session.user = req.body // 用户的信息存储到session中
    req.session.islogin = true // 用户的登录状态存储到session中

    res.send({
    
     status: 0, msg: '登录成功' })
})
(4) Get data from session
  • can directly obtain previously stored data from the req.session object. The sample code is as follows:
// 获取用户姓名的接口
app.get('/api/username', (req, res) => {
    
    
    //判断用户是否登录    
    if (!req.session.islogin) {
    
    
        return res.send({
    
     status: 1, msg: 'fail' })
    }
    res.send({
    
    
        status: 0,
        msg: 'success',
        username: req.session.user.username,
    })
})
(5) Clear session
  • Call the req.session.destroy() function to clear the session information saved by the server.
// 退出登录的接口
app.post('/api/logout', (req, res) => {
    
    
    //清空 Session 信息
    req.session.destroy()
    res.send({
    
    
        status: 0,
        msg: '退出登录成功',
    })
})

5. JWT authentication mechanism

(1) Limitations of Session authentication
  • Required for Session authentication mechanism配合 Cookie 才能实现. Since cookies do not support cross-domain access by default, cross-domain session authentication can only be achieved when 前端跨域请求后端接口 is involved. 需要做很多额外的配置 is required.
  • When the front end requests the backend interface不存在跨域问题, 推荐使用 Session identity authentication mechanism.
  • When the front-end needs to request the back-end interface across domains, it is not recommended to use the Session authentication mechanism, and it is recommended to use the JWT authentication mechanism.
(2) What is JWT
  • JWT (English full name: JSON Web Token) is currently. 最流行跨域认证解决方案
(3) How JWT works
  • The user's information is stored in the client browser in the form of a Token string. The server authenticates the user's identity by restoring the Token string.

image-20230615094911072

(4) Components of JWT
  • JWT usually consists of three parts, namely Header(头部)、Payload(有效荷载)、Signature(签名).
  • The three are separated by English., the format is as follows:

image-20230615101059964

  • Here is an example of a JWT string:

image-20230615101122129

(5) Meaning of JWT components
  • Payload: Real user information, which is a string generated after encrypting user information.
  • Header 和 Signature: The part of 安全性相关 is just to ensure the security of Token

image-20230615101811561

(6) How to use JWT
  • After the client receives the JWT returned from the server, it usually stores it in localStorage or sessionStorage.
  • After that, every time the client communicates with the server, it must bring this JWT string for identity authentication. The recommended approach is to place the JWT in the field of HTTP 请求头 in the following format: Authorization

image-20230615110310190

6. Using JWT in Express

(1) Install JWT related packages
  • Install two JWT related packages:npm install jsonwebtoken express-jwt

    • jsonwebtoken: Generate JWT string

    • express-jwt: Parse JWT string and restore it to JSON object

(2) Import JWT related packages
  • Use the require() function to import the two JWT-related packages:
// 生成 JWT 字符串

const jwt = require('jsonwebtoken')

// 将 JWT 字符串解析还原成 JSON 对象

const expressJWT = require('express-jwt')
(3) Define secret key
  • In order保证 JWT 字符串的安全性 to prevent the JWT string from being cracked by others during network transmission, we need to specifically define one for 加密 and Secret key of 解密:
    • When generating a JWT string, you need to use secret 密钥 to perform 加密 on the user's information, and finally get the encrypted JWT string
    • When parsing and restoring the JWT string to a JSON object, you need to use secret 密钥解密
// secret密钥的本质:就是一个字符串
const secretKey = 'mysecret'
(4) Generate JWT string after successful login
  • Call the method provided by the jsonwebtoken package to encrypt the user's information into a JWT string and respond to the client: sign()
// 登录接口
app.post('/api/login', function(req, res) {
    
    
    // 将 req.body 请求体中的数据,转存为 userinfo 常量
    const userinfo = req.body
        // 登录失败
    if (userinfo.username !== 'admin' || userinfo.password !== '000000') {
    
    
        return res.send({
    
    
            status: 400,
            message: '登录失败!',
        })
    }
    // 登录成功
    // 在登录成功之后,调用 jwt.sign() 方法生成 JWT 字符串。并通过 token 属性发送给客户端
    // 参数1:用户的信息对象
    // 参数2:加密的秘钥
    // 参数3:配置对象,可以配置当前 token 的有效期
    // 记住:千万不要把密码加密到 token 字符中
    const tokenStr = jwt.sign({
    
     username: userinfo.username }, secretKey, {
    
     expiresIn: '30s' })
    
    res.send({
    
    
        status: 200,
        message: '登录成功!',
        token: tokenStr, // 要发送给客户端的 token 字符串
    })
})
(5) Restore JWT string to JSON object
  • Every time the client accesses those authorized interfaces, it needs to actively send the Token string to the server for identity authentication through请求头中的 Authorization 字段.
  • At this time, the server can automatically parse and restore the Token sent by the client into a JSON object through the express-jwt middleware:
// 使用app.use() 来注册中间件
// expressJWT(secret:secretKey})就是用来解断Token的中间件
// .unless({path:[/A\/api\//]})用来指定哪些接口不需要方问权限
app.use(expressJWT({
    
     secret: secretKey }).unless({
    
     path: [/^\/api\//] }))
(6) Use req.user to obtain user information
  • Whenexpress-jwt this middleware is successfully configured, you can use the req.user object in those interfaces with permissions to access the JWT string The user information parsed from , the sample code is as follows:
// 这是一个有权限的 API 接口
app.get('/admin/getinfo', function(req, res) {
    
        
    console.log(req.user)
    res.send({
    
    
        status: 200,
        message: '获取用户信息成功!',
        data: req.user, // 要发送给客户端的用户信息
    })
})
(7) Capture errors generated after failure to parse JWT
  • When using express-jwt to parse the Token string, if the Token string sent by the client is 过期 or 不合法, a will be generated. The error of a>解析失败 affects the normal operation of the project.
  • We can capture this error and perform related processing through Express 的错误中间件. The sample code is as follows:
// 使用全局错误处理中间件,捕获解析 JWT 失败后产生的错误
app.use((err, req, res, next) => {
    
    
    // 这次错误是由 token 解析失败导致的
    if (err.name === 'UnauthorizedError') {
    
    
        return res.send({
    
    
            status: 401,
            message: '无效的token',
        })
    }
    res.send({
    
    
        status: 500,
        message: '未知的错误',
    })
})

Guess you like

Origin blog.csdn.net/liyou123456789/article/details/131241474