intern-study icon indicating copy to clipboard operation
intern-study copied to clipboard

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

Open deligent-ant opened this issue 7 years ago • 0 comments

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



deligent-ant avatar Aug 04 '18 04:08 deligent-ant