Cookie and jwt analysis

1. cookie

  • Cookies are stored in the client, and Cookies can be divided into 内存Cookie和硬盘Cookie.
    • Memory cookies are maintained by the browser and stored in the memory. The cookies will disappear when the browser is closed, and their existence time is short;
    • Hard disk cookies are stored on the hard disk and have an expiration time. They will not be cleared until the user manually clears them or the expiration time expires;
  • How to determine whether a cookie is a memory cookie or a hard disk cookie?
    • 没有设置过期时间, by default the cookie is a memory cookie and will be automatically deleted when the browser is closed;
    • 有设置过期时间 (max-age=过期时间), and cookies whose expiration time is not 0 or a negative number are hard disk cookies and will only be deleted manually or when they expire;
  • The default cookie is a memory cookie, also known as a memory cookie 会话cookie, which is automatically deleted when the browser is closed.
  • You can set the expiration time by setting expires or max-age.
    • expires: The setting is Date.toUTCString(), the setting format is;expires=date-in-GMTString-format;
    • max-age: Set expiration seconds,;max-age=max-age-in-seconds (for example, one year is 60 60 24*365);

1.1 Server-side cookie settings

  • cookie verification
    • Set cookies on the server side
    • The client (browser) obtains the cookie set by the server and saves it
    • When accessing under the same scope (domain name/path), cookies will be carried dynamically
    • The server can verify the user's identity through the cookie carried by the client
const koa = require('koa');

const koaRouter = require('@koa/router');
const app = new koa()
/**
* @description:
* @param {type} 服务端设置cookie
* @param {type} 客户端(游览器)获取服务器设置的cookie,并且做一个保存
* @param {type} 在同一个作用域下进行访问(域名/路径), 会在动携带cookie
* @param {type} 服务器可以通过客户端携带的cookie验证用户的身份
* @return: 
*/
const userRouter = new koaRouter({
    
     prefix: '/users' })
userRouter.get('/login', (cxt, next) => {
    
    
	// 服务器设置会话cookie
	cxt.cookies.set('slogin', 'ikun', {
    
    
		maxAge: 60 * 1000
	})
	cxt.body = '登录成功'
	next()
})

userRouter.get('/list', (cxt, next) => {
    
    
	// 当上个接口登录成功后 这个cookie会自动携带
	const cookie = cxt.cookies.get('slogin')
	console.log(cookie);
	if (cookie) {
    
    
		cxt.body = cookie
	}
})
app.use(userRouter.routes())
app.listen(9000, () => {
    
    
	console.log('服务器启动成功~');
})
  • Cookies are transmitted in clear text, so there are certain security issues.

At the same time, when sending an HTTP request, we found that the browser carried all our cookies ( note: the browser will only carry the cookie that contains the path value of the cookie in the URL of the current request ), and it is key: value expressed in the form. Use ; to separate multiple cookies.

-

1.2 Cookie signature and salting

  • The signature in the cookie is based on session , which is another mechanism for recording client status and is saved on the server.
  1. Session workflow: When the browser accesses the server and sends the first request, 服务器端会创建一个 session 对象,生成一个类似于 key,value 的键值对then the key (cookie) is returned to the browser (client). The next time the browser visits, it carries the key (cookie) and finds the corresponding session(value), use 户的信息都保存在 session 中.
  • Install npm install koa-session
const koa = require('koa');
const koaSession = require('koa-session');
const koaRouter = require('@koa/router');
const app = new koa()
//  npm i koa-session
const session = koaSession({
    
    
	key: 'sessionId',
	httpOnly:true,   // 不允许通过JS获取cookie
	maxAge:5*1000,    // 过期时间
	rolling:true, // 每次响应时,刷新session的有效期
	signed:true   // 加密签名认证,防止数据被篡改,必传
},app)

app.keys=['aaa']  // 加盐操作 ,双层验证
app.use(session)
const userRouter = new koaRouter({
    
     prefix: '/users' })
userRouter.get('/login', (cxt, next) => {
    
    
	cxt.session.slogin='ikun'
	cxt.body = '登录成功'
})

userRouter.get('/list', (cxt, next) => {
    
    
	const cookie = cxt.session.slogin
	console.log(cookie);
	if (cookie) {
    
    
		cxt.body = cookie
	}else{
    
    
		cxt.body='没有权限访问'
	}
})
app.use(userRouter.routes())
app.listen(9000, () => {
    
    
	console.log('服务器启动成功~');
})

1.3 The difference between cookie and session

  1. Cookie data is stored on the client browser, and session data is stored on the server.

  2. Cookies are not very secure and are passed in clear text, so there are security issues;

  3. The session will be saved on the server for a certain period of time. Increased access will occupy server performance. To alleviate server performance problems, cookies should be used.

  4. The data saved by a single cookie cannot exceed 4K, and many browsers limit a site to save up to 20 cookies.

  5. For other clients outside the browser (such as iOS, Android), cookies and sessions must be set manually;

2. JWT token

  • A JWT is actually a string, which consists of three parts, header, payload and signature.

  • The Token generated by JWT consists of three parts:

  • The header is used to describe the most basic information about the JWT, such as its type and the algorithm used for signature. This can also be represented as a JSON object.

    • alg: the encryption algorithm used, the default is HMAC SHA256 (HS256), using the same key for encryption and decryption;
    • type: JWT, fixed value, usually written as JWT;
    • It will be encoded through the base64Url algorithm;
  • payload

    • The data carried, for example, we can put the user's id and name in the payload;
    • By default, it will also carry iat (issued at), the issuance time of the token;
    • We can also set the expiration time: exp (expiration time);
      - will be encoded through the base64Url algorithm
  • signature

    • Set one and perform the HS256secretKey algorithm by merging the results of the first two ;
    • HMACSHA256(base64Url(header)+.+base64Url(payload), secretKey);
    • But if the secretKey is exposed, it is a very dangerous thing, because then the token can be simulated and the token can be decrypted;
  • JWT principle article reference

  • Understanding front-end and back-end interaction diagrams
    Insert image description here

  • POSTMAN sets token global sharing
    Insert image description here

2.1 HS256 symmetric encryption

  • HS256 (HMAC with SHA-256) is a symmetric algorithm in which only one key is shared between the two parties. Since the same key is used to generate signatures and verify signatures, care must be taken to ensure that the key is not compromised
const koa = require('koa');
const jwt = require('jsonwebtoken');
const koaRouter = require('@koa/router');
const app = new koa()
// npm i jsonwebtoken

const userRouter = new koaRouter({
    
     prefix: '/users' })
userRouter.get('/login', (cxt, next) => {
    
    
	//  1. 颁发token
	const payload = {
    
     name: 'admin', password: 123456 }

	const secretKey = "aaaaaaaaaaaaaa"
	const token = jwt.sign(payload, secretKey,  {
    
     
		 expiresIn:30
	})

	cxt.body={
    
    
		code:200,
		token:token,
		message:'登录成功'
	}
})

userRouter.get('/list', (cxt, next) => {
    
    
  //  获取客户端携带过来的token
	const authorization=cxt.headers.authorization
	const token=authorization.replace('Bearer','')
	console.log(token);
	// 2. 验证token
	try {
    
    
		const result=jwt.verify(token,escretkey)
		console.log(result);
	} catch (error) {
    
    
		cxt.body = 'token过期,没有权限访问,请重新登录'
	}

})
app.use(userRouter.routes())
app.listen(9000, () => {
    
    
	console.log('服务器启动成功~');
})

2.2 RS256 asymmetric encryption

  • RS256 (RSA signature using SHA-256) is an asymmetric algorithm that uses a public/private key pair: the identity provider uses 私钥生成签名, J WT 的使用方获取公钥以验证签名. Since public keys (compared to private keys) do not require protection, most identity providers make them easily obtainable and usable by consumers (usually via a metadata URL)
  • With asymmetric encryption, RS256:
    • Private key: used to issue tokens;
    • Public key: used to verify the token;
  • Generate a pair of private and public keys using git Bash
  1. openssl
  2. genrsa -out private.key 2048
  3. rsa -in private.key -pubout -out public.key
const koa = require('koa');
const jwt = require('jsonwebtoken');
const fs = require('fs');
const koaRouter = require('@koa/router');
const app = new koa()

const pubilcKey = fs.readFileSync('./keys/public.key')
const reivateKey = fs.readFileSync('./keys/private.key')
const userRouter = new koaRouter({
    
     prefix: '/users' })
userRouter.get('/login', (cxt, next) => {
    
    
	//  1. 颁发token
	const payload = {
    
     name: 'admin', password: 123456 }

	const token = jwt.sign(payload, reivateKey, {
    
    
		// 修改加密方式 HS256改为RS256加密
		expiresIn: 60, algorithm: 'RS256'
	})
	cxt.body = {
    
    
		code: 200,
		token: token,
		message: '登录成功'
	}
})

userRouter.get('/list', (cxt, next) => {
    
    
	//  获取客户端携带过来的token
	const authorization = cxt.headers.authorization
	const token = authorization.replace('Bearer', '')
	// 2. 验证token
	try {
    
    
		const result = jwt.verify(token, pubilcKey, {
    
    algorithms: ['RS256'] })
		console.log(result);
	} catch (error) {
    
    
		cxt.body = 'token过期,没有权限访问,请重新登录'
	}

})
app.use(userRouter.routes())
app.listen(9000, () => {
    
    
	console.log('服务器启动成功~');
})

Guess you like

Origin blog.csdn.net/weixin_46104934/article/details/131928557
jwt