byte-fe / intern-study

实习生互助学习
MIT License
33 stars 6 forks source link

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

Open deligent-ant opened 6 years ago

deligent-ant commented 6 years ago

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' })