前面帖子身份驗證中Cookies與 Tokens比較已經說明令牌比cookie好,下面是AngularJS中的實現。伺服器後端首先安裝express-jwt:$ npm install express-jwt配置express保護/api的每個調用:var expressJwt = require("express-jwt");// We are going to protect /api routes with JWTapp.use("/api", expressJwt({secret: secret}));app.use(express.json());app.use(express.urlencoded());Angular應用使用用戶證書通過AJAX提交POST:

app.post("/authenticate", function (req, res) { //TODO validate req.body.username and req.body.password //if is invalid, return 401 if (!(req.body.username === "john.doe" && req.body.password === "foo[author]bar[/author]")) { res.send(401, "Wrong user or password"); return; } var profile = { first_name: "John", last_name: "Doe", email: "[email protected]", id: 123 }; // We are sending the profile inside the token var token = jwt.sign(profile, secret, { expiresInMinutes: 60*5 }); res.json({ token: token });});

下面是調用 /api/restricted獲得一個資源,其證書檢查由expressJwt中間件執行。

app.get("/api/restricted", function (req, res) { console.log("user " + req.user.email + " is calling /api/restricted"); res.json({ name: "foo" });});

前端Angular.js客戶端首先用AngularJS 獲得JWT的令牌,為了這樣做我們還需要用戶證書,我們將將創建一個表單讓用戶輸入他們的用戶名和密碼。

<div ng-controller="UserCtrl"> <span></span> <form ng-submit="submit()"> <input ng-model="user.username" type="text" name="user" placeholder="Username" /> <input ng-model="user.password" type="password" name="pass" placeholder="Password" /> <input type="submit" value="Login" /> </form></div>

一個控制器處理提交的action:

myApp.controller("UserCtrl", function ($scope, $http, $window) { $scope.user = {username: "john.doe", password: "foo[author]bar[/author]"}; $scope.message = ""; $scope.submit = function () { $http .post("/authenticate", $scope.user) .success(function (data, status, headers, config) { $window.sessionStorage.token = data.token; $scope.message = "Welcome"; }) .error(function (data, status, headers, config) { // Erase the token if the user fails to log in delete $window.sessionStorage.token; // Handle login errors here $scope.message = "Error: Invalid user or password"; }); };});

現在我們已經有JWT存儲在sessionStorage中,如果這個令牌被設置,我們可以為每個發出請求設置Authorization 頭部,只要用$http方式即可,頭部值部分使用Bearer<token>

myApp.factory("authInterceptor", function ($rootScope, $q, $window) { return { request: function (config) { config.headers = config.headers || {}; if ($window.sessionStorage.token) { config.headers.Authorization = "Bearer " + $window.sessionStorage.token; } return config; }, response: function (response) { if (response.status === 401) { // handle the case where the user is not authenticated } return response || $q.when(response); } };});myApp.config(function ($httpProvider) { $httpProvider.interceptors.push("authInterceptor");});

儘管sessionStorage並不是所有瀏覽器支持,你可以使用 polyfill替代cookie保存在localStorage,這個數據能夠持久到瀏覽器標籤頁關閉。最後,我們能夠向一個授權資源發出請求:

$http({url: "/api/restricted", method: "GET"}).success(function (data, status, headers, config) { console.log(data.name); // Should log "foo"});

伺服器後端控制台會顯示:user [email protected] is calling /api/restricted本案例源碼下載:github[該貼被banq於2014-01-08 13:35修改過]
推薦閱讀:

查看原文 >>
相关文章