egg學習(二)-- 結合redis實現用戶登錄註冊生成token

簡介:
想要實現基於node搭建的服務器的用戶的登錄和註冊首先要了解登錄註冊的相關業務邏輯;

輸入賬號密碼
查詢是否存在
存在
匹配
不匹配
用戶註冊
數據庫
用戶登錄
數據庫
密碼是否匹配
返回登錄成功並生成token
返回登錄失敗

一、用戶註冊

用戶註冊就是簡單的像數據庫添加一個數據

controller文件

// app/controller/admin.js
const Controller = require('egg').Controller;
class AdminController extends Controller {
  // 用戶註冊
  async sign() {
    const ctx = this.ctx;
    const req = ctx.request.body
    var signResult = await ctx.service.admin.sign(req)
    ctx.body = signResult
  }
}
module.exports = AdminController;

model文件

// app/model/admin.js
module.exports = app => {
    const mongoose = app.mongoose;
    const Schema = mongoose.Schema;
   
    const AdminSchema = new Schema({
      // studentid:{type:Number,unique:true,required:true,ref:'ClassStudent'},
      user_id: { 
        type: Schema.ObjectId 
      },
      username: { 
        type: String,
        required:true,
        unique:true // 確保每個用戶名是唯一的
      },
      password: { 
        type: String,
        required:true
      },
    });
    return mongoose.model('admin', AdminSchema,'adminUser');
  } 

service

// app/service/admin.js
const Service = require('egg').Service;

class AdminService extends Service {
  // 添加用戶
  async sign(req) {
    const ctx = this.ctx;
    console.log(req);
    return ctx.model.Admin.create(req).then(res => {
      return { success: true, msg: 'success', code: 0} ;
    }).catch(err => {
      return { success: false, err };
    });
  }
}
module.exports = AdminService ;

在保證可以註冊之後我們再來看看登錄

二、登錄

在登錄過程中後臺會返回用戶一個token來作爲一個標識,但是實際開發中,token更多的不是存儲在現有的數據庫中,而是存儲在 redis 這個臨時的空間中;

redis是一個以key-value存儲的數據庫結構型服務器,它支持的數據結構類型包括:字符串(String)、鏈表(lists)、哈希表(hash)、集合(set)、有序集合(Zset)等。爲了保證讀取的效率,redis把數據對象都存儲在內存當中,它可以支持週期性的把更新的數據寫入磁盤文件中。而且它還提供了交集和並集,以及一些不同方式排序的操作。

egg也有用來連接redis插件 egg-redis 在本地開發環境下~你需要先下載一個redis來作爲你的本地暫存的數據庫,

redis 下載地址
下載並安裝,配置開發環境,然後在文件目錄下用命令窗口輸入命令 redis-cli 來啓動這個庫;

實現用戶登錄功能:
controller文件

// app/controller/admin.js
const Controller = require('egg').Controller;
const jwt = require('jsonwebtoken'); // 生成token的插件模塊,用npm 安裝

class AdminController extends Controller {
  // 用戶登錄
  async login() {
    const ctx = this.ctx;
    const { app } = this
    const req = ctx.request.body
    var loginResult = await ctx.service.admin.login(req)
    if(loginResult.code === 0){
      // 表示登錄成功
      let time = 10 //token過期時間 這裏的時間是以分鐘來計算
      let token = generateToken({}, time)// 生成token,generateToken是一個自定義的函數
      app.redis.set(loginResult.msg[0]._id, token) // 把token存入redis
      loginResult.token = token
    }
    ctx.body = loginResult
  }
}
// 自定義的生成token的函數
function  generateToken(data, time){
  let created = Math.floor(Date.now() / 1000);
  // let cert = fs.readFileSync(path.join(__dirname, '../public/rsa_private_key.pem'));//私鑰
  let token = jwt.sign({
      data,
      exp: created + time
  },"suiyi");
  return token;
}

module.exports = AdminController;

service

// app/service/admin.js
const Service = require('egg').Service;

class AdminService extends Service {
  // 用戶登錄
  async login(req) {
    const ctx = this.ctx;
    console.log(req);
    return ctx.model.Admin.find({username:req.username}).then(res => {
      if(res[0].password === req.password){
        return { success: true, msg: res, code: 0} 
      } else {
        return { success: false, msg: res, code: -1}
      }
    })
  }
}
module.exports = AdminService ;

我們嘗試登錄一個用戶:
這是模擬登錄的接口請求,返回了登錄成功的信息並生成了一個token
這個時候用戶的狀態是登錄狀態,我們再去看看redis中的數據,打開redis的命令窗口,上面說到的是如何存入自己的token到redis中,用的是 set() 方法,當需要校驗用戶的token的時候,我們要叢redis中獲取用戶的token,用到的是 get()
在這裏插入圖片描述
該數據已經存在於redis數據庫中

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章