关于eggjs:Eggjs使用redis实现跨域缓存Fetch发送跨域请求

前后端拆散开发时,咱们的前端申请是跨域申请,会造成session和cookie生效的问题。
在浏览多种解决办法后,我抉择了应用redis来实现session的解决方案,确保前端应用跨域申请的状况下,后端能够维持用户session.

起因

为什么抉择redis来实现跨域下的session呢?

我浏览了多种跨域session失落的解决办法,但都没有失效,于是最初抉择了redis才解决了这个问题。

前后端增加credential后,浏览器无奈主动加载第三方cookie, 服务端的session和cookie依然失落。

前端Fetch跨域申请

const data = {key:"value"};// 参数
const myHeaders = new Headers();
myHeaders.append('Access-Control-Allow-Origin', 'http://localhost:3000/');
   // 设置Access-Control-Allow-Credentials,跨域申请带受权
myHeaders.append('Access-Control-Allow-Credentials', 'true');
   // 设置mode为cors,进行跨域申请
myHeaders.append('mode', 'cors');
   // 设置Content-Type, 参数格局
myHeaders.append('Content-Type', 'application/x-www-form-urlencoded')
var urlencoded = new URLSearchParams()
for (let key in data) {
      urlencoded.append(key, data[key])
}
const requestOptions = {
      method: 'POST',
      headers: myHeaders,
      body: urlencoded,
      redirect: 'follow',
      // 设置为include确保跨域申请放弃cookie
      credentials: 'include', 
}
fetch(api, requestOptions).then(response=>response.json());

Egg跨域配置

// config.default.js

'use strict'
const path = require('path')
module.exports = appInfo => {
  const config = {
        mode: 'file',
        errorHandler: {
          match: '/'
        },
  }

     // 设置security里的csrf敞开,容许跨域申请
  config.security = {
        domainWhiteList: ['*'],
        csrf: {
          enable: false
        }
  }
  // 设置cors插件配置, origin为前端的起源(带credentials无奈设置为*)
  // 设置credentials为true,返回的Header带有Access-Control-Allow-Credentials为true
  config.cors = {
        origin: 'http://localhost:3000',
        credentials: true,
        allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH'
  }
  // 这里设置egg自带的session,但跨域申请依然失落session
  config.session = {
        key: 'WheelFit',
        maxAge: 30 * 24 * 3600 * 1000, // 30 days
        httpOnly: true,
        encrypt: true,
        renew: true
  }

  // 自定义中间件, sessionToken为鉴权中间件,在收到申请后获取session里存储的token
  config.middleware = ['sessionToken', 'errorHandler']

  return {
    ...config,
  }
}
// plugin.js
'use strict';
// 增加cors插件用于回复跨域申请
// npm i --save egg-cors
module.exports = {
  cors: {
        enable: true,
        package: 'egg-cors',
     }
};

这个配置是在其余的解决跨域session失落问题的文章中找到的,实践上增加credientals即可放弃session,但我这里并没有失效,跨域申请依然会失落session,并且给response设置的cookie也不能被浏览器获取到。然而应用postman,发送非跨域申请,是能够记录的session的。


无奈我只能抉择应用redis维持跨域申请的session

Redis 配置

前端Fetch申请依然放弃不变(尽管credential曾经不须要设置)
后端须要新增egg-redis插件

// plugin.js
'use strict';
// 增加cors插件用于回复跨域申请
// npm i --save egg-cors
// npm i --save egg-redis
module.exports = {
  cors: {
        enable: true,
        package: 'egg-cors',
     },
  redis: {
    enable: true,
    package: 'egg-redis',
  },
};
// config.default.js
config.redis = {
  client: {
    port: 6379, // Redis port
    host: '127.0.0.1', // Redis host
    password: '',
    db: 0
  }
}

应用redis设置值

// login.js
async login(){
  const {ctx} = this;
  // login operation
  // login successfully
  const token = generateToken();
  ctx.app.redis.set(`token${userid}`, token);
  return (ctx.body={success:true, userid: userid})
}


// check session
async session_token() {
    const {ctx} = this;
    const {userid, token} = ctx.request.body;
    const redis_token = ctx.app.redis.get(`token${userid}`);
    if(redis_token === token) {
        return (ctx.body={success: true});
    }
    return (ctx.body={success: false});
}

这样咱们在服务端应用redis为跨域申请设置缓存状态,咱们还能够设置定时工作,删除该状态。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理