Egg學習_Setp2_Sequelize,session-redis配置,token實現

使用Sequelize操做MySQL

Sequelize是Node.js v4及更高版本的基於promise的ORM。它支持方言PostgreSQL,MySQL,SQLite和MSSQL,並具備堅實的事務支持,關係,讀取複製等等。Egg官方也有egg-sequelize的插件,因此這裏使用它來進行代碼中全部SQL操做.html

添加並開啓sequelize插件:node

// {workdir}/config/plugin.js
// 掛在到app下,經過app.sequelize使用
exports.sessionRedis = {
  enable: true,
  package: "egg-sequelize"
};

啓動前建立表:redis

// {workdir}/app.js
module.exports = app => {
    app.beforeStart(async function () {
        await app.model.sync({ force: false }); // false 爲不覆蓋 true會刪除再建立
    });
};

添加model文件:npm

// {workdir}/app/model/user.js 必定要使用此目錄
// 掛在到ctx下經過 ctx.model.User.fn()使用
module.exports = app => {
  const { STRING, INTEGER, DATE, BIGINT } = app.Sequelize;
  const User = app.model.define("user", {
    login: STRING,
    id: {
      type: BIGINT(11),
      autoIncrement:true,
      primaryKey : true,
      unique : true
    },
    role: {
      type: INTEGER,
      default: 0
    },
    name: STRING(30),
    passwd: STRING(32),
    age: INTEGER,
    last_sign_in_at: DATE,
    created_at: DATE,
    updated_at: DATE
  });
  return User;
};

存在問題 添加外鍵沒有解決
文檔中能夠經過app.createAnonymousContext()建立一個匿名ctx,但這裏報錯,因此沒法獲取其它model,這裏設置外鍵須要promise

sequelize經常使用API:session

Model.findOne({ where: {filed: 'value'} }).then(...) // query
Model.create({ filed1: 'value', filed2: 'value' }).then(...) // create
Model.destroy() // delete
// ...

官方文檔地址: http://docs.sequelizejs.com
中文APIapp

session和redis配置

Egg已經內置了Seesion插件,經過ctx.session能夠直接使用,
能夠將session自定義外部存儲,實現以下async

// {workdir}/app.js
module.exports = app => {
  app.sessionStore = {
    * get (key) {
      // return value;
    },
    * set (key, value, maxAge) {
      // set key to store
    },
    * destroy (key) {
      // destroy key
    },
  };
};

但這裏使用了egg-redisegg-session-redis兩個插件來將session存儲到redis中.
啓用插件:fetch

// {workdir}/config/plugin.js
exports.sessionRedis = {
  enable: true,
  package: "egg-session-redis"
};

exports.redis = {
  enable: true,
  package: "egg-redis"
};

插件配置:ui

// {workdir}/config/config.default.js
const database = "egg";
const redisHost = "192.168.189.130";
const dbHost = "localhost";
module.exports = appInfo => {
  const config = {};
  config.redis = { // 單個redis
    client: {
      port: 6379,          // Redis port
      host: redisHost,   // Redis host
      password: "",
      db: 0
    }
  };
  config.sessionRedis = {
    key: "EGG_SESSION",
    maxAge: 24 * 3600 * 1000, // 1 天
    httpOnly: true,
    encrypt: false
  };
  return config;
};

session使用實例:

// {workdir}/app/controller/auth.js
...
async login(ctx) {
    ctx.validate(userRule);
    const user = await ctx.service.auth.login(ctx.request.body);
    ctx.assert(user, "用戶名或密碼錯誤");
    const token = await app.genToken(user.id, ctx.request.ip);
    ctx.session.user = user.id;
    ctx.session.token = token.id;
    ctx.status = 204;
}
...

token實現

token主要用來記錄一些用戶登陸的信息,存儲在db中.
首先定義token的model:

// {workdir}/app/model/token.js
module.exports = app => {
    const { STRING, DATE, BIGINT, BOOLEAN } = app.Sequelize;
    const Token = app.model.define("token", {
        id: {
            type: BIGINT(11),
            autoIncrement:true,
            primaryKey : true,
            unique : true
        },
        user: BIGINT(11),
        expire: DATE,
        ip: STRING,
        valid: BOOLEAN
    });
    return Token;
};

token DB 操做的service層代碼:

// {workdir}/app/service/token.js
const moment = require("moment");
module.exports = app => {
    class Token extends app.Service {
        async fetchOne (id) {
            const token = await this.ctx.model.Token.find({
                where: { id: id }
            });
            return token;
        }
        async genToken (userId, ip) {
            const expire = new Date(moment().add(1, "days"));
            const token = await this.model.Token.create({ expire, ip, user: userId, valid: true });
            return token;
        };
    }
    return Token;
};

登陸後session中記錄token的id ....在中間件中添加token驗證 ....

相關文章
相關標籤/搜索