Análisis de cookies y jwt.

1. galleta

  • Las cookies se almacenan en el cliente y las cookies se pueden dividir en 内存Cookie和硬盘Cookie.
    • Las cookies de memoria son mantenidas por el navegador y almacenadas en la memoria, las cookies desaparecerán cuando se cierre el navegador y su tiempo de existencia es corto;
    • Las cookies del disco duro se almacenan en el disco duro y tienen un tiempo de vencimiento. No se borrarán hasta que el usuario las borre manualmente o expire el tiempo de vencimiento;
  • ¿Cómo determinar si una cookie es de memoria o de disco duro?
    • 没有设置过期时间, por defecto la cookie es de memoria y se eliminará automáticamente cuando se cierre el navegador;
    • 有设置过期时间 (max-age=过期时间), y las cookies cuyo tiempo de caducidad no sea 0 o un número negativo son cookies del disco duro y sólo se eliminarán manualmente o cuando caduquen;
  • La cookie predeterminada es una cookie de memoria, también conocida como cookie de memoria 会话cookie, que se elimina automáticamente cuando se cierra el navegador.
  • Puede establecer el tiempo de vencimiento configurando la fecha de vencimiento o la edad máxima.
    • expires: La configuración es Date.toUTCString(), el formato de configuración es;expires=date-in-GMTString-format;
    • max-age: Establecer segundos de vencimiento,;max-age=max-age-in-segundos (por ejemplo, un año es 60 60 24 *365);

1.1 Configuración de cookies del lado del servidor

  • verificación de cookies
    • Establecer cookies en el lado del servidor
    • El cliente (navegador) obtiene la cookie configurada por el servidor y la guarda
    • Al acceder bajo el mismo ámbito (nombre de dominio/ruta), las cookies se transportarán dinámicamente
    • El servidor puede verificar la identidad del usuario a través de la cookie llevada por el cliente
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('服务器启动成功~');
})
  • Las cookies se transmiten en texto claro, por lo que existen ciertos problemas de seguridad.

Al mismo tiempo, al enviar una solicitud HTTP, descubrimos que el navegador llevaba todas nuestras cookies ( nota: el navegador solo llevará la cookie que contiene el valor de la ruta de la cookie en la URL de la solicitud actual ), y es clave: valor expresado en el formulario. Utilice ; para separar varias cookies.

-

1.2 Firma de galleta y salazón

  • La firma en la cookie se basa en la sesión , que es otro mecanismo para registrar el estado del cliente y se guarda en el servidor.
  1. Flujo de trabajo de la sesión: cuando el navegador accede al servidor y envía la primera solicitud, 服务器端会创建一个 session 对象,生成一个类似于 key,value 的键值对la clave (cookie) se devuelve al navegador (cliente). La próxima vez que el navegador visita, lleva la clave (cookie) y encuentra la sesión correspondiente ( valor), utilice 户的信息都保存在 session 中.
  • Instalar npm instalar 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 La diferencia entre cookie y sesión

  1. Los datos de las cookies se almacenan en el navegador del cliente y los datos de la sesión se almacenan en el servidor.

  2. Las cookies no son muy seguras y se transmiten en texto claro, por lo que existen problemas de seguridad;

  3. La sesión se guardará en el servidor durante un período de tiempo determinado. Un mayor acceso ocupará el rendimiento del servidor. Para aliviar los problemas de rendimiento del servidor, se deben utilizar cookies.

  4. Los datos guardados por una sola cookie no pueden exceder los 4K y muchos navegadores limitan un sitio para guardar hasta 20 cookies.

  5. Para otros clientes fuera del navegador (como iOS, Android), las cookies y las sesiones deben configurarse manualmente;

2. Ficha JWT

  • Un JWT es en realidad una cadena que consta de tres partes: encabezado, carga útil y firma.

  • El Token generado por JWT consta de tres partes:

  • El encabezado se utiliza para describir la información más básica sobre el JWT, como su tipo y el algoritmo utilizado para la firma. Esto también se puede representar como un objeto JSON.

    • alg: el algoritmo de cifrado utilizado, el predeterminado es HMAC SHA256 (HS256), que utiliza la misma clave para cifrado y descifrado;
    • tipo: JWT, valor fijo, generalmente escrito como JWT;
    • Será codificado mediante el algoritmo base64Url;
  • carga útil

    • Los datos transportados, por ejemplo, podemos poner la identificación y el nombre del usuario en la carga útil;
    • De forma predeterminada, también llevará iat (emitido en), el momento de emisión del token;
    • También podemos establecer el tiempo de vencimiento: exp (tiempo de vencimiento);
      - se codificará mediante el algoritmo base64Url
  • firma

    • Establezca uno y ejecute el algoritmo HS256secretKey fusionando los resultados de los dos primeros ;
    • HMACSHA256(base64Url(encabezado)+.+base64Url(carga útil), clavesecreta);
    • Pero si la clave secreta está expuesta, es algo muy peligroso, porque entonces el token se puede simular y descifrar;
  • Referencia del artículo principal de JWT

  • Comprender los diagramas de interacción front-end y back-end
    Insertar descripción de la imagen aquí

  • POSTMAN establece el intercambio global de tokens
    Insertar descripción de la imagen aquí

2.1 Cifrado simétrico HS256

  • HS256 (HMAC con SHA-256) es un algoritmo simétrico en el que solo se comparte una clave entre las dos partes. Dado que la misma clave se utiliza para generar firmas y verificar firmas, se debe tener cuidado para garantizar que la clave no se vea comprometida.
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 Cifrado asimétrico RS256

  • RS256 (firma RSA que utiliza SHA-256) es un algoritmo asimétrico que utiliza un par de claves pública/privada: el proveedor de identidad utiliza 私钥生成签名, J WT 的使用方获取公钥以验证签名. Dado que las claves públicas (en comparación con las claves privadas) no requieren protección, la mayoría de los proveedores de identidad hacen que los consumidores puedan obtenerlas y utilizarlas fácilmente (generalmente a través de una URL de metadatos).
  • Con cifrado asimétrico, RS256:
    • Clave privada: utilizada para emitir tokens;
    • Clave pública: utilizada para verificar el token;
  • Genere un par de claves públicas y privadas usando 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('服务器启动成功~');
})

Supongo que te gusta

Origin blog.csdn.net/weixin_46104934/article/details/131928557
Recomendado
Clasificación