1. 程式人生 > >如何在node和vue以axios作為互動的專案中使用cookie或者set-cookie

如何在node和vue以axios作為互動的專案中使用cookie或者set-cookie

    最近在用vue+node+mysql重構專案,前端用的vue+typescript寫的,後端用的express框架,沒有用太多的外掛,用原始擼的。

    專案地址https://github.com/Vitaminaq/node-mysql 歡迎交流。

    剛好有個登陸頁面,為了儲存使用者資訊,必須得使用token。之前的思維一直侷限在,使用者登陸時,生成token,並用放在data裡面返回來,客戶端自己去儲存,需要驗證的頁面把token放在請求的headers的authorization欄位裡面,後端每次去讀這個欄位就可以驗證了,但是總感覺有點繁瑣。樣本我也貼一下吧,token我是用的jwt來生成的,至於存在哪裡,瀏覽器那幾種方法都還可以。

// 前端程式碼
axios.create({
     baseURL: 'http://127.0.0.1:3005',
     timeout: 5000,
     headers: {
         'Content-Type': 'application/json',
         'Cache-Control': 'no-cache',
         'authorization': window.sessionStorage.getItem('token')
     }
});

後面想到了響應頭裡面有個set-cookie欄位,非常的簡便,因為是全自動的,伺服器自動把資訊存入瀏覽器的cookie裡面,用來記錄驗證資訊非常方便。原生node的語法大致如下:

res.setHeader('Set-Cookie', [`token = ${token};path: '/'; secure: false; signed: false,userId = 1`]);
如果有多個欄位,第二個引數可以是陣列,結構就是key=value,後面跟一些對cookie配置的屬性。
domain String Cookie的域名。預設為應用程式的域名
encode Function 用於cookie值編碼的同步函式。預設為encodeURIComponent
expires Date GMT中cookie的到期日。如果未指定或設定為0,則建立會話cookie
httpOnly Boolean 標記cookie只能由Web伺服器訪問。
maxAge Number 方便的選項,用於設定相對於當前時間的到期時間(以毫秒為單位)。
path String Cookie的路徑。預設為“/”
secure Boolean 將cookie標記為僅與HTTPS一起使用。
signed Boolean 指示cookie是否應該簽名。
sameSite Boolean or String “SameSite” Set-Cookie屬性的值。更多資訊,訪問https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-4.1.1

這些引數基本是用不太到的,但是大家可以去研究下,有個時候可以會涉及到cookie共享,各級域名間的共享等,就不多提了,世界之大,真要研究,好玩的太多了,一樣東西都能腿玩年。

express的語法大概如下(配置欄位跟上面是一樣的):

// 差不多就是把原生的拆成了單個的,看起來比較清晰。key, value, options,多個值的時候需要多行書寫。
res.cookie('token', token, { path: '/', secure: false, signed: false });
res.cookie('nickname', nickname, { path: '/', secure: false, signed: false });

光設定這個是不夠的,因為不屬於跨域共享資源,所以需要一些設定的支援,客戶端由於用了axios,就只說下axios吧。

在它官網上有個詳細的請求頭引數配置,裡面有一個withCredentials欄位,大概配置如下:(對於非axios的,其實也差不多,axios只不過是基於http的封裝,萬變不離其宗,把這個欄位加在你的請求頭裡就ok了)

        axios.create({
            baseURL: 'http://127.0.0.1:3005',
            timeout: 5000,
            withCredentials: true, //表示跨域請求時是否需要使用憑證,預設為false
            headers: {
                'Content-Type': 'application/json',
                'Cache-Control': 'no-cache'
            }
        });

node端也需要進行該配置,大概如下:

app.all('*', function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "http://127.0.0.1:8088");
    res.header("Access-Control-Allow-Headers", "Content-Type, authorization, Cache-Control");
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
    res.header('Access-Control-Allow-Credentials', 'true'); // 就是這個欄位
    next();
});

該欄位可選。它的值是一個布林值,表示是否允許傳送Cookie。預設情況下,Cookie不包括在CORS請求之中。設為true,即表示伺服器明確許可,Cookie可以包含在請求中,一起發給伺服器。這個值也只能設為true,如果伺服器不要瀏覽器傳送Cookie,刪除該欄位即可。成功登陸的響應頭大概如下圖,然後後面的請求,請求頭裡面都會自帶這個cookie,無需管理。

cookie設定成功

到這裡差不多就摸索完了,如果覺得問題解決了,歡迎點贊,有什麼疑問也可以討論,歡迎交流。