Skip to content

session实现登录与登出的简单实现 #22

@deligent-ant

Description

@deligent-ant

session实现登录与登出的简单实现

登录用户的信息存与mysql,mysql上的操作基于objection做了一下封装,把对应的数据库表操作方法挂在fastify的sever实列上,用户是否已经登录通过cookie实现,只是cookie上存储的只是用户信息的一个映射key,也就是sessionId,通过sessionId作索引,在mysql上匹配到对应的用户信息。

实现步骤

  1. 建两个表user表和session表:分别存用户信息、sessionId与user的映射关系。
  2. 用户访问网站时候校验cookie中的sessionId是否存在有效,有效则把对应的用户信息挂在requsert返回,如果无效或是不存在,不作处理。
  3. 如果有效,用户可以在nuxt的中间间,middleware中的req拿到fastify挂上去的用户信息。
    4.如果无效,用户要进行登录操作,这时候发请求校验user表,是否正确,正确就开始生成sessionId,存在用户浏览器的cookie上。
    5 注销操作,清除session会话,以及session中的记录。

简单代码如下:

'use strict'
//用户名要唯一

const fp = require('fastify-plugin')
const uid = require('uid-safe').sync
const sessionPlugin = async (app, options) => {
  let sessionIdName = options.sessionName || 'sessionId_stock_level2'
  let userModel = await app.getQueryModel({
    psm: '11111111',
    table: '222222'
  })
  let sessionModel = await app.getQueryModel({
    psm: '33333333',
    table: '4444444444'
  })
  app.addHook('preHandler', async (req, reply) => {
    const sessionId = req.cookies[sessionIdName]
    if (sessionId) {
      const r = await sessionModel
        .query()
        .where({ sessionId })
        .andWhere('expires', '<', new Date())
        .catch(err => err)
      if (Array.isArray(r) && r.length > 0) {
        req.session = r[0]
      }
    }
  })

  app.post('/login', async (req, reply) => {
    let { body } = req
    let name = body.name
    let password = body.password
    const userName = await userModel
      .query()
      .where('name', name)
      .catch(err => console.log(err))
    if (userName.length === 0) {
      return { code: 1, data: '用户名输入错误!' }
    } else {
      const userPassword = await userModel.query().where({ name, password })
      if (userPassword.length === 0) {
        return { code: 1, data: '密码输入错误!' }
      } else {
        const sessionId = uid(24)
        let maxAge = options.maxAge || 60 * 60 * 1000
        let expires = new Date(Date.now() + maxAge)
        let resInsert = await sessionModel
          .query()
          .insert({ sessionId, expires, name })
          .catch(err => err)
        reply
          .setCookie(sessionIdName, sessionId, {
            domain: '',
            path: '/',
            expires: new Date(expires),
            httpOnly: true
          })
          .send({ code: 0, data: '登陆成功!' })
      }
    }
  })
}

module.exports = fp(sessionPlugin, {
  fastify: '>=1.2.0',
  name: '@fe/byted-auth'
})

附上一个基于json ,而非mysql的简单实现

'use strict'
//用户名要唯一

const fp = require('fastify-plugin')
const sessionPlugin = async (app, options = {}) => {
  // console.log(app.CONFIG)
  let maxAge = options.maxAge || 24 * 60 * 60 * 100
  let sessionIdName = options.sessionName || 'sessionId_stock_level2'
  const { WHITELIST } = app.CONFIG

  app.addHook('preHandler', async (req, reply) => {
    const sessionId = req.cookies[sessionIdName]
    if (sessionId) {
      let userInfos = {}
      let time = new Date()
      const isAvaiable = WHITELIST.some(item => {
        if (
          item.sessionId === sessionId &&
          item.expires < time &&
          item.group === 'SZ'
        ) {
          userInfos = item
          return true
        }
        return false
      })
      if (isAvaiable) {
        req.session = userInfos
      } else {
        req.session = null
      }
    }
  })

  app.post('/szlevel2/login', async (req, reply) => {
    let expires = new Date(Date.now() + maxAge)
    let sessionId = ''
    let { body } = req
    let name = body.name
    let password = body.password
    const isAvaiable = WHITELIST.some(item => {
      if (
        item.name === name &&
        item.password === password &&
        item.group === 'SZ'
      ) {
        sessionId = item.sessionId
        return true
      }
      return false
    })
    if (isAvaiable) {
      reply
        .setCookie(sessionIdName, sessionId, {
          domain: '',
          expires: new Date(expires),
          httpOnly: true
        })
        .send({ code: 0, data: { name, message: '登陆成功' } })
    } else {
      reply.send({ code: 1, data: '输入错误!' })
    }
  })

  app.post('/szlevel2/logout', async (req, reply) => {
    reply
      .setCookie(sessionIdName, '')
      .send({ code: 0, data: 'logout success!' })
  })
}

module.exports = fp(sessionPlugin, {
  fastify: '>=1.2.0',
  name: '@fe/byted-auth'
})

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions