COOKIE跨域獲取問題

COOKIE跨域獲取問題

最近開發項目時,須要用到後端設置session,用戶請求時,更具session設置給前端的cookie獲取session的值,因爲項目採用的是前端後端分離(先後端不在一個域上),故出現瞭如題所示問題:html

功能介紹

  1. 用戶在登錄時後端返回驗證碼圖片,同時生成session,存儲驗證碼的值,
  2. 用戶的登錄時提交驗證碼的值,若是相同經過,不相同從新獲取驗證碼

image

代碼前端

// 獲取驗證碼
  getCaptcha() {
    const { ctx } = this;
    const captcha = svgCaptcha.createMathExpr({
      inverse: false, // 翻轉顏色
      fontSize: 50, // 字體大小
      noise: 1, // 噪聲線條數
      width: 110, // 寬度
      height: 38, // 高度
      color: true, // 驗證碼的字符是否有顏色,默認沒有,若是設定了背景,則默認有
    });
    ctx.session.maxAge = 1000 * 60; // 1分鐘
    ctx.session.renew = false; // 設置在連續訪問的時候不刷新剩餘時間
    ctx.session.verifyCode = captcha.text; // 設置session
    this.success({
      code: captcha.data,
    });
  }

 // login
  async login() {
    const { ctx } = this;
    const { account, password, code } = ctx.request.body;
    const verifyCode = ctx.session.verifyCode;
    console.log(verifyCode);

    if (code !== verifyCode) {
      this.error('驗證碼錯誤', 444);
      return;
    }
    ...
  }

問題來了

一切訪問正常,可是vue

  1. 用戶登陸時,後臺取不到session,值爲undefined
  2. 前端cookie裏也無相應的值

解決

通過查閱,緣由是cookie跨域,不能訪問的緣由,須要對代碼進行相關設置:ios

參考: https://blog.csdn.net/weixin\_45932463/article/details/110350608

前端(vue axios):chrome

// 進行一些全局配置
axios.defaults.baseURL = 'http://127.0.0.1:7001'; //egg後臺的地址
axios.defaults.timeout = 5000;
axios.defaults.withCredentials = true; // 讓axios發送請求的時候帶上cookie

設置後,訪問以下:(這種狀況下,還須要後端設置)axios

image

後端(用的是阿里的eggjs)後端

<span>注意:下面有origin的多種設置方式,特別是多個跨域,值得收藏哦</span>跨域

config.cors = {
    // origin: '*',
    // origin: 'http://127.0.0.1:9384',
    origin(ctx) {
      // return "*"; // 容許來自全部域名請求
      // return ctx.header.origin;// 當*沒法使用時,使用這句,一樣容許全部跨域
      // return 'http://localhost:8080'; //單個跨域請求
      // 容許多個跨域
      const allowCors = [
        'http://localhost:9384',
        'http://127.0.0.1:9384',
        'http://172.16.92.62:9384',
      ];
      return allowCors.indexOf(ctx.header.origin) > -1 ? ctx.header.origin : '';
    },
    credentials: true, // 前臺能夠攜帶cookies 無此選項的話,仍是上面的跨域
    allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS',
  };

設置後瀏覽器

image

能夠正常獲取到後臺設置的cookie了(session會自動向前端設置一個cookei)cookie

至此基本登錄能夠正常進行了

可是

若是你用的是google瀏覽器,或者內核是chrome的瀏覽器,若是版本高於80

後臺獲取session,仍是undefined

緣由

image

上圖能夠看到,這種cookie沒有成功

Chrome 51開始,瀏覽器的 Cookie新增長了一個 SameSite屬性,用來防止 CSRF攻擊和用戶追蹤。
該設置當前默認是關閉的,但在 Chrome 80以後,該功能默認已開啓

參考 https://www.ruanyifeng.com/bl...

解決方法:

用戶:

  1. 打開Chrome設置,將chrome://flags/#same-site-by-default-cookies禁用,而後重啓瀏覽器。

image

  1. 使用低版本瀏覽器(chrome 小於80版本)

開發者:

  1. 方案1. 將SameSite屬性值改成None, 同時 將secure屬性設置爲true。且須要將後端服務域名必須使用https協議訪問。
  2. 因爲設置SameSite = None,有SCRF風險,因此,最佳方案是用token代替Cookie方式做驗證。

本例中的解決方案推薦使用Redis解決

相關文章
相關標籤/搜索