koa2+vue+axios搭建一個部落格臺管理系統之session踩坑

重慶崽兒Brand發表於2019-02-16

原文釋出在我的個人部落格:http://www.brandhuang.com

下面就開始我的表演

一、先說一下我部落格管理系統和服務端用到的東西

我的部落格的服務端是採用的koa2 + MySQL,後臺管理介面採用的是:Vue+ElementUi+axios。這都是些常規組合,沒有什麼好說的。

二、服務端

==koa2-cors:== 用來是設定跨域請求;

// 官方推薦配置
var Koa = require(`koa`);
var cors = require(`koa2-cors`);
 
var app = new Koa();
app.use(cors());

==koa-session-minimal:== 因為koa本身並不能處理 session,在 koa 中處理 session 需要其他中介軟體的支援,在網上一番搜尋後,發現很多人用的這個,於是我也用了。。。;
==koa-mysql-session:== 用來吧session存到資料庫裡面

// 這兩個模組用法

const session = require(`koa-session-minimal`);
const MysqlStore = require(`koa-mysql-session`);
// session儲存配置
const sessionMysqlConfig= {
    user: config.database.USERNAME,
    password: config.database.PASSWORD,
    database: config.database.DATABASE,
    host: config.database.HOST,
}

// 配置session中介軟體
app.use(session({
    key: `USER_SID`,
    store: new MysqlStore(sessionMysqlConfig),
    cookie: {                   // 與 cookie 相關的配置
        domain: `localhost`,    // 寫 cookie 所在的域名
        path: `/`,              // 寫 cookie 所在的路徑
        maxAge: 1000 * 300,      // cookie 有效時長
        httpOnly: true,         // 是否只用於 http 請求中獲取
        overwrite: false        // 是否允許重寫
    }
}))

一切準備就緒,開始試試session吧

1. 在輸入正確的使用者名稱和密碼後,先設定一下session的資訊

 ctx.session = {
     user: res[0][`account`],
     id: res[0][`id`]
}

此時,我們能看到在資料庫和瀏覽器的登陸請求中已經有了session值,如圖:
::: hljs-center

browsercookie.png
mysqlsession.png

:::

但是
當我請求其他介面的時候,發現瀏覽器的請求頭裡面的cookie不見了!!!,對,沒有了。。。不管我發起什麼請求,在後端請求裡面都拿不到我需要的使用者資訊

//如果後端拿到了瀏覽器的cookie
//在後端可以通過
ctx.session.user  //拿到我們登陸成功後設定的使用者資訊

拿到的始終是一個空的 =={}==,
通過去各大搜尋引擎搜尋發現:==axios預設是不讓ajax請求頭部攜帶cookie的==,,需要手動設定:

axios.defaults.withCredentials=true;//讓ajax攜帶cookie

好吧,手動設定就設定吧,也不是什麼難事。

設定完後重新登陸。。。
阿西吧!!!!登不上去了,控制檯報錯了。。。。

Failed to load http://localhost:3500/login: Response to preflight request doesn`t pass access control check: 
The value of the `Access-Control-Allow-Credentials` header in the response is `` which must be `true` when the request`s credentials mode is `include`.
 Origin `http://localhost:8080` is therefore not allowed access. 
The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

怎麼又跨域了?!!之前不是設定了允許跨域請求嗎???
。。。我們們繼續上搜尋引擎找找去。。。

header資訊 Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin不可以為 ``,因為 `` 會和 Access-Control-Allow-Credentials:true 衝突,需配置指定的地址

好吧,我們又去修改之前的cors的配置

// 修改前
app.use(cors())
//  修改後如下
app.use(cors({
    origin: [ `http://localhost:8080`], // 允許這個域名的 跨域請求
    exposeHeaders: [`WWW-Authenticate`, `Server-Authorization`],
    maxAge: 5,
    credentials: true,
    allowMethods: [`GET`, `POST`, `DELETE`],
    allowHeaders: [`Content-Type`, `Authorization`, `Accept`],
}));

設定後終於可以正常登陸了,通過==ctx.session==也能成功拿到使用者資訊了

緊接著,另一個問題又誕生了

我的服務端是前端和後臺管理系統共用的。他們呢在不同的埠。。。但是這個跨域只允許設定一個域名。。。

不管了,先睡覺,小命要緊,明天再來!

不整了,已經用jwt,基於token驗證方式了,不用糾結請求攜帶cookie時的跨域的問題了

相關文章