2016-08-30 190 views
0

我正在創建一個帶有SQL,Angularjs,Node.js和Express的Angularjs單頁應用程序,它使用護照和基本身份驗證進行登錄。當用戶登錄時,他們可以訪問路由來編輯數據庫中的項目。這一切正常工作,問題是隻要瀏覽器不刷新,cookie就會被髮送。瀏覽器刷新後,由AngularJS設置的Cookie將被忽略

如果瀏覽器刷新,令牌不再與請求一起發送,所以用戶無法再訪問路由,因爲沒有該請求的令牌。但是,如果您查看瀏覽器中的cookie,則令牌仍然存在,並且只要服務器未重新啓動,令牌仍然有效。

那裏還有其他由Google Analytics設置的Cookie,但每次都會隨請求一起發送。如果我在app.run中設置了一個cookie,它每次都會持續並隨請求一起發送,它只是使用登錄工廠創建的cookie,在瀏覽器刷新後不會發送。

我的登錄工廠看起來是這樣的:

'use strict'; 
 

 
import * as customFunctions from '../../shared/methods/common-functions.js'; 
 

 
const userLoggingRESTResources = (app) => { 
 

 
    app.factory('userLoggingRESTResources', ['$http', '$base64', '$cookies', '$window', ($http, $base64, $cookies, $window) => { 
 
    return (user, callback) => { 
 
     return { 
 
     signIn: (user, callback) => { 
 
      var encoded = $base64.encode(user.username + ':' + user.password); 
 
      $http.get('/auth/login', { 
 
       headers: { 
 
       'Authorization': 'Basic ' + encoded 
 
       } 
 
      }) 
 
      .success((data) => { 
 

 
       $cookies.put('token', data.token); 
 
       $cookies.put('interopAdmin', data.admin); 
 
       $window.sessionStorage.token = data.token; 
 
       $http.defaults.headers.common.Authorization = data.token; 
 
       callback(null); 
 
      }) 
 
      .error((data) => { 
 
       callback(data); 
 
      }) 
 
     } 
 

 
     }; 
 
    } 
 

 

 
    }]) 
 
} 
 

 
module.exports = userLoggingRESTResources;

我登錄路由看起來是這樣的:

router.get('/login', passport.authenticate('basic', { 
 
    session: false 
 
    }), (req, res) => { 
 
    let userJSON = { 
 
     randomString: req.user.dataValues.randomString, 
 
     id: req.user.dataValues.id 
 
    }; 
 
    res.req.headers.authorization = 'hahaha'; 
 
    for (let key in res.req.rawHeaders) { 
 
     if (res.req.rawHeaders[key].slice(0, 5) === 'Basic') { 
 
     res.req.rawHeaders[key] = 'Basic xxxx'; 
 
     } 
 

 
    } 
 
    req.user.$modelOptions.instanceMethods.generateToken(userJSON, process.env.SECRET_KEY, (err, token) => { 
 
     if (err) { 
 
     console.log(err); 
 
     return res.status(500).json({ 
 
      msg: 'error generating token' 
 
     }); 
 
     } 
 

 
     res.status('200').header('token', token).json({ 
 
     token: token, 
 
     'admin': req.user.dataValues.isAdmin 
 
     }); 
 
    }); 
 
    });

我全光照克來自故宮的eat模塊來處理令牌解碼:

'use strict'; 
 

 
const eat = require('eat'); 
 
const models = require('../models'); 
 
const User = models.User; 
 
const clc = require('cli-color'); 
 

 
module.exports = (secret) => { 
 
    return (req, res, next) => { 
 
    let token = req.cookies.token || req.headers.token || req.body.token || req.headers.authorization; 
 
    if (!token) { 
 
     console.log(clc.white.bgRed('no token in request')); 
 
     return res.status(401).json({ 
 
     msg: 'not authorized' 
 
     }); 
 
    } 
 
    eat.decode(token, secret, (err, decoded) => { 
 
     if (err) { 
 
     console.log(clc.white.bgRed('Error, login failed: '), err); 
 
     return res.status(401).json({ 
 
      msg: 'not authorized' 
 
     }); 
 
     } 
 

 
     User.findOne({ 
 
      where: { 
 
      id: decoded.id 
 
      } 
 
     }) 
 
     .then((user) => { 
 
      if (!user) { 
 
      console.log(clc.white.bgRed('user not found')); 
 
      return res.status(401).json({ 
 
       msg: 'not authorized' 
 
      }); 
 
      } 
 

 
      req.user = user; 
 
      next(); 
 
     }) 
 
     .error((error) => { 
 
      console.log(clc.white.bgRed('Error: '), err); 
 
      return res.status(401).json({ 
 
      msg: 'not authorized' 
 
      }); 
 
     }); 
 
    }); 
 
    }; 
 
};

如果有你想看到的代碼的另一部分,請讓我知道。感謝您提前幫助您!

+0

使用角度存儲爲您的令牌https://github.com/auth0/angular-storage –

+0

只是要清楚。您的控制檯中是否出現「請求中無令牌」錯誤? – cyberwombat

+0

@Yashua是的,你是對的,我得到'沒有要求令牌'。 – CascadiaJS

回答

0

你說的曲奇是不是發送的,那麼你說的曲奇在瀏覽器中是。這兩種說法相互矛盾。如果他們在瀏覽器中,也許你的Angular應用程序只需要閱讀它們?如果他們沒有發送,也許你需要在服務器上使用某種會話來存儲令牌/不管什麼,這樣你就可以把它作爲一個cookie發回去。

+0

Cookie由來自登錄路由的數據響應中的Angular設置,然後它們存在於瀏覽器中,然後cookie從瀏覽器發送,並隨後發送$ http get請求到我的節點路由。如果頁面沒有刷新,cookies會隨着每個後續請求一起發送,一切正常。但是,如果瀏覽器刷新,Cookie仍在瀏覽器中,但由於某種原因,它們不再與請求一起發送。對不起,如果我沒有說得好。 – CascadiaJS

0

所以我想通了。我使用/admin/login作爲我的登錄路由,/admin/whatever作爲其他需要認證的路由,所以cookie設置路徑爲:/admin/login,因爲我在第一次登錄時只使用該路由,所以這是第一次發送cookie的原因,但不在隨後的請求中。

要解決它,我將路徑設置爲根,當我設置的Cookie是這樣的:

$cookies.put('token', data.token, {'expires': expireDate, 'path': '/'});

現在的Cookie會與所有請求發送!感謝所有的提示和幫助:-)