案例20課實戰(zhàn)鑒權(quán)_第1頁
案例20課實戰(zhàn)鑒權(quán)_第2頁
案例20課實戰(zhàn)鑒權(quán)_第3頁
案例20課實戰(zhàn)鑒權(quán)_第4頁
已閱讀5頁,還剩8頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、Koa實戰(zhàn) - 鑒權(quán)session-cookie方式cookie原理Header Set-Cookie負責(zé)設(shè)置cookie請求傳遞Cookiesession的原理解釋開課吧web全棧架構(gòu)師/ cookie.jsconst http = require("http") const session = http.createServer(req, res) => / 觀察cookie存在console.log('cookie:', req.headers.cookie)const sessionKey = 'sid'const cookie

2、 = req.headers.cookieif(cookie && cookie.indexOf(sessionKey) > -1 ) res.end('Come Back ')/ 簡略寫法未必具有通用性const pattern = new RegExp($sessionKey=(;+);?s*) const sid = pattern.exec(cookie)1 console.log('session:',sid ,session ,sessionsid) else const sid = (Math.random() * 99999

3、999).toFixed()/ 設(shè)置cookieres.setHeader('Set-Cookie', $sessionKey=$sid;)/ cookie.jsconst http = require("http") http.createServer(req, res) => if(req.url = '/favicon.ico')res.end('') return/ 觀察cookie存在console.log('cookie:', req.headers.cookie)/ 設(shè)置cookieres.

4、setHeader('Set-Cookie', 'cookie1=abc;') res.end('hello cookie!').listen(3000)原理實現(xiàn)原理:1. 服務(wù)器在接受客戶端首次 時在服務(wù)器端創(chuàng)建seesion,然后保存seesion(我們可以將seesion保存在 內(nèi)存中,也可以保存在redis中,推薦使用后者),然后給這個session生成一個唯一的標(biāo)識字符串,然后在 響應(yīng)頭中種下這個唯一標(biāo)識字符串。2. 簽名。這一步通過秘鑰對sid進行簽名處理,避免客戶端修改sid。(非必需步驟)3. 瀏覽器中收到請求響應(yīng)的時候會 響應(yīng)頭

5、,然后將sid保存在本地cookie中,瀏覽器在下次http請求的請求頭中會帶上該 下的cookie信息,4. 服務(wù)器在接受客戶端請求時會去 請求頭cookie中的sid,然后根據(jù)這個sid去找服務(wù)器端保存的該客戶端的session,然后 該請求是否合法。koa中的session使用: npm i koa-session -S開課吧web全棧架構(gòu)師const koa = require('koa') const app = new koa()const session = require('koa-session')/ 簽名key keys作用 用來對cooki

6、e進行簽名app.keys = 'some secret'/ 配置項const SESS_CONFIG = sessionsid = name : 'laowang' res.end('Hello')res.end('hello cookie!').listen(3000)key: 'kkb:sess', / cookie鍵名maxAge: 86400000, / 有效期,默認一天httpOnly: true, / 僅服務(wù)器修改signed: true, / 簽名cookie;/app.use(session(SE

7、SS_CONFIG, app);/ 測試app.use(ctx => if (ctx.path = '/favicon.ico') return;/ 獲取let n = ctx.session.count | 0;/ 設(shè)置ctx.session.count = +n; ctx.body = '第' + n + '次 ');app.listen(3000)使用redis sessionconst redis = require('redis');const client = redis.createClient(6379,&#

8、39;localhost');client.set('hello','This is a value');client.get('hello',function (err,v) console.log("redis get ",v);)安裝: npm i -S koa-redis配置使用:/ koa-redisconst redisStore = require('koa-redis'); const redis = require('redis')const redisClient =

9、 redis.createClient(6379, "localhost");var wrapper = require('co-redis'); var client = wrapper(redisClient);app.use(session( key:'kkb:sess',store: redisStore(client) / 此處可以不必指定client開課吧web全棧架構(gòu)師, app);app.use(ctx => /./查看redis中存儲的數(shù)據(jù)redisClient.keys('*',(err,keys)=

10、>console.log(keys); keys.forEach(key=>redisClient.get(key,(err,val)=> console.log(val););案例:通過session實現(xiàn)用戶鑒權(quán)登錄頁面,./public/login-session.html開課吧web全棧架構(gòu)師<html><head><script src="<script src="</head><body><div id="app"><div><input

11、 v-model="username" /><input v-model="password" /></div><div><button click="login">Login</button><button click="logout">Logout</button><button click="getUser">GetUser</button></div><di

12、v><button click="logs=">Clear Log</button></div><!- 日志 -><ul><li v-for="(log,idx) in logs" :key="idx"> log </li></ul></div><script>/ 這行代碼很關(guān)鍵,請求時攜帶cookie axios.defaults.withCredentials = true; ercept

13、ors.response.use(response => koa-bodyparser用于 post請求體安裝:npm i koa-bodyparser -S配置開課吧web全棧架構(gòu)師/ index.jsconst session = require('koa-session')/ 簽名key keys作用 用來對cookie進行簽名app.keys = 'some secret'/ 配置項const SESS_CONFIG = key: 'kkb:sess', / cookie鍵名maxAge: 86400000, / 有效期,默認一天h

14、ttpOnly: true, / 僅服務(wù)器修改signed: true, / 簽名cookie;/app.use(session(SESS_CONFIG, app);app.logs.push(JSON.stringify(response.data); return response;);var app = new Vue( el: "#app", data: username: "test", password: "test", logs: ,methods: login: async function() await axios

15、.post("/users/login", username: this.username, password: this.password);,logout: async function() await axios.post("/users/logout");,getUser: async function() await axios.get("/users/getUser"););</script></body></html>登錄/注銷接口,./routes/users.jsrouter.po

16、st("/login", async ctx => / 需安 odyparserconst body = ctx.request; console.log("body", body);/登錄邏輯,略/登錄 ,設(shè)置session ctx.session.userinfo = body.username; ctx.body = ok: 1,message: "登錄 ");router.post("/logout", async ctx => /設(shè)置sessiondelete ctx.session.user

17、info; ctx.body = ok: 1,message: "登出系統(tǒng)");router.get("/getUser", async ctx => ctx.body = ok: 1,message: "獲取數(shù)據(jù) ", userinfo: ctx.session.userinfo;);路由守衛(wèi)中間件,./middleware/auth.jsmodule.exports = async (ctx, next) => if (!ctx.session.userinfo) ctx.body = ok: 0,message: &

18、quot;用戶未登錄" else await next();應(yīng)用守衛(wèi),./routes/users.js開課吧web全棧架構(gòu)師const bodyparser = require('koa-bodyparser') app.use(bodyparser() router.get("/getUser", require("./middleware/auth"), async ctx => .) Token 驗證原理案例:令牌認證登錄頁,public/login-token.html<html><head&g

19、t;<script src="<script src="</head>"></script> "></script><body><div id="app"><div><input v-m ="username" /><input v-m ="password" /></div><div><button v-on:click="login&

20、quot;>Login</button><button v-on:click="logout">Logout</button><button v-on:click="getUser">GetUser</button></div><div><button click="logs=">Clear Log</button></div><!- 日志 ->開課吧web全棧架構(gòu)師開課吧web全棧架構(gòu)師<u

21、l><li v-for="(log,idx) in logs" :key="idx"> log </li></ul></div><script> erceptors.request.use(config => const token = window.localStorage.getItem("token"); if (token) / 是否存在token,如果存在的話,則每個http header都加上token/ Bearer是JWT的認證頭

22、部信息mon"Authorization" = "Bearer " + token;return config;,err => return Promise.reject(err););erceptors.response.use( response => app.logs.push(JSON.stringify(response.data); return response;,err => app.logs.push(JSON.stringify(response.data); return Promise.reje

23、ct(err););var app = new Vue( el: "#app", data: username: "test", password: "test", logs: ,methods: login: async function() const res = await axios.post("/users/login-token", username: this.username,password: this.password);localStorage.setItem("token"

24、;, res.data.token);,logout: async function() localStorage.removeItem("token");,getUser: async function() await axios.get("/users/getUser-token");登錄接口安裝依賴: npm i jsonwebtoken koa-jwt -S接口編寫,routes/users.jsconst jwt = require("jsonwebtoken"); const jwtAuth = require("

25、;koa-jwt"); const secret = "it's a secret"router.post("/login-token", async ctx => const body = ctx.request;/登錄邏輯,略/設(shè)置sessionconst userinfo = body.username;ctx.body = message: "登錄 ", user: userinfo,/ 生成 token 返回給客戶端token: jwt.sign(data: userinfo,/ 設(shè)置 token 過

26、期時間,一小時后,秒為exp: Math.floor(Date.now() / 1000) + 60 * 60,secret););router.get( "/getUser-token", jwtAuth(secret),async ctx => / 驗證通過,state.user console.log(ctx.state.user);/獲取session ctx.body = message: "獲取數(shù)據(jù) ", userinfo: ctx.state.user.data;);開課吧web全棧架構(gòu)師);</script></b

27、ody></html>JWT( JSON WEB TOKEN)原理1. Bearer Token包含三個組成部分:令牌頭、payload、哈希eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoiYWJjIiwicGFzc3dvcmQiOiIxMTExMTEifSwi ZXhwIjoxNTU3MTU1NzMwLCJpYXQiOjE1NTcxNTIxMzB9.pjGaxzX2srG_MEZizzmFEy7JM3t8tjkiu3yULgzFwUk1. 簽名:默認使用base64對payload編碼,使用h

28、s256算法對令牌頭、payload和密鑰進行簽名生成哈希2. 驗證:默認使用hs256算法對hs256算法對令牌中數(shù)據(jù)簽名并將結(jié)果和令牌中哈希比對/ jsonwebtoken.jsconst jsonwebtoken = require('jsonwebtoken') const secret = '12345678'const opt = secret: 'jwt_secret', key: 'user'const user = username: 'abc', password: '111111

29、9;const token = jsonwebtoken.sign( data: user,/ 設(shè)置 token 過期時間exp: Math.floor(Date.now() / 1000) + (60 * 60), secret)console.log('生成token:' + token)/ 生成token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoiYWJjIiwicGFzc3dv cmQiOiIxMTExMTEifSwiZXhwIjoxNTQ2OTQyMzk1LCJpYXQiOjE1N

30、DY5Mzg3OTV9.VPBCQgLB7XPBq3RdHK9WQMkPp3dw65JzEKm_LZZjP9Yconsole.log(' :', jsonwebtoken.verify(token, secret, opt)/ : data: username: 'abc', password: '111111' ,/ exp: 1546942395,/ iat: 1546938795 參考文檔: jsonwebtoken、koa-jwt 阮一峰 JWT解釋開課吧web全棧架構(gòu)師 web token-tutorial.htmlOAuth(開放 )

31、概述: 登入主要基于OAuth 2.0。OAuth協(xié)議為用戶 的 提供了一個安全的、開放而又簡易的標(biāo)準。與以往的 方式不同之處是OAUTH的 使第 觸及到用戶的帳號信息(如用戶名與 ), 即第 無需使用用戶的用戶名與 就可以申請獲得該用戶 的 ,因此OAUTH是安全的。OAuth登錄流程案例:OAuth登錄登錄頁面 index.html開課吧web全棧架構(gòu)師<html><head><script src="<script src="</head><body><div id="app">

32、;<a href='/</div></body></html>"></script> "></script>/login'>login with</a>登錄接口 index.jsconst Koa = require('koa')const router = require('koa-router')() const static = require('koa-static') const app = new Koa();const axios

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論