Use Sa-Token para concluir a autenticação de login na arquitetura de separação de front-end e back-end

1. Análise de arquitetura

Atualmente, a maioria dos sistemas foi projetada com uma arquitetura de "separação de front-end e back-end", e a autenticação tradicional do modo de sessão não é mais adequada para essa arquitetura (ou muito código adicional precisa ser escrito para adaptação especial ).

Sa-Token é uma estrutura leve de autenticação de autoridade java, especialmente criada para arquiteturas de separação de front-end e back-end. Ele resolve principalmente uma série de problemas relacionados à autoridade, como autenticação de login, autenticação de autoridade, logon único, OAuth2 e autenticação de gateway de microsserviço.

Gitee endereço de código aberto: https://gitee.com/dromara/sa-token

Este artigo apresentará os projetos de separação de front-end e back-end sob a arquitetura Springboot e como usar o Sa-Token para concluir a autenticação de login de maneira conveniente.

Primeiro introduza a dependência Sa-Token no projeto:

<!-- Sa-Token 权限认证 -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.34.0</version>
</dependency>

Observação: se você estiver usando SpringBoot 3.x, basta sa-token-spring-boot-starteralterar para sa-token-spring-boot3-starter.

2. Sem modo de cookie

Sem modo de cookie: Refere-se especificamente a terminais que não suportam a função de cookie. De um modo geral, é o que costumamos dizer - o modo de separação front-end e back-end .

Os métodos convencionais de autenticação no lado da Web geralmente são Cookie模式preenchidos por , e os cookies têm duas características:

  1. Gravável pelo controle de back-end.
  2. Enviado automaticamente em cada solicitação.

Isso nos permite concluir todo o processo de autenticação sem nenhuma operação especial no código front-end (porque todo o processo é concluído pelo controle back-end)

Para a função de cookies, a maioria das pessoas ficará confusa neste momento, como realizar a autenticação?

Veja os truques, a resposta é realmente muito simples:

  • Se o back-end não puder controlar a escrita, o front-end grava sozinho. (A dificuldade está em como o backend passa o Token para o frontend )
  • Se cada solicitação não puder ser enviada automaticamente, envie-a manualmente. (A dificuldade está em como o front-end passa o token para o back-end e o back-end o lê ao mesmo tempo )

3. O back-end retorna o token para o front-end

  1. Primeira chamada StpUtil.login(id)para fazer login.
  2. Call StpUtil.getTokenInfo()Retorna os parâmetros detalhados do token da sessão atual.
    • Este método retorna um objeto com duas propriedades principais: tokenNamee tokenValue(o nome do token e o valor do token).
    • Passe esse objeto para o primeiro plano e deixe o pessoal do front-end salvar esses dois valores localmente.

Exemplo de código:

// 登录接口
@RequestMapping("doLogin")
public SaResult doLogin() {
   
	// 第1步,先登录上 
	StpUtil.login(10001);
	// 第2步,获取 Token 相关参数 
	SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
	// 第3步,返回给前端 
	return SaResult.data(tokenInfo);
}

4. O front-end envia o token para o back-end

  1. Seja um aplicativo ou um pequeno programa, os métodos de entrega são semelhantes.
  2. Ou seja, insira o token na requisição headerno formato: {tokenName: tokenValue}.
  3. Pegue o uni-app clássico de framework cross-end como exemplo:

Método 1, simples e rude

// 1、首先在登录时,将 tokenValue 存储在本地,例如:
uni.setStorageSync('tokenValue', tokenValue);

// 2、在发起ajax请求的地方,获取这个值,并塞到header里 
uni.request({
   
	url: 'https://www.example.com/request', // 仅为示例,并非真实接口地址。
	header: {
   
		"content-type": "application/x-www-form-urlencoded",
		"satoken": uni.getStorageSync('tokenValue')		// 关键代码, 注意参数名字是 satoken 
	},
	success: (res) => {
   
		console.log(res.data);	
	}
});

Método 2, mais flexível

// 1、首先在登录时,将tokenName和tokenValue一起存储在本地,例如:
uni.setStorageSync('tokenName', tokenName); 
uni.setStorageSync('tokenValue', tokenValue); 

// 2、在发起ajax的地方,获取这两个值, 并组织到head里 
var tokenName = uni.getStorageSync('tokenName');	// 从本地缓存读取tokenName值
var tokenValue = uni.getStorageSync('tokenValue');	// 从本地缓存读取tokenValue值
var header = {
   
	"content-type": "application/x-www-form-urlencoded"
};
if (tokenName != undefined && tokenName != '') {
   
	header[tokenName] = tokenValue;
}

// 3、后续在发起请求时将 header 对象塞到请求头部 
uni.request({
   
	url: 'https://www.example.com/request', // 仅为示例,并非真实接口地址。
	header: header,
	success: (res) => {
   
		console.log(res.data);	
	}
});
  1. Desde que tokeno valor seja passado para o back-end dessa maneira, o Sa-Token pode ler automaticamente o valor do token para autenticação, assim como o lado do PC tradicional.
  2. Você pode ter dúvidas, eu tenho que ajaxescrever uma pilha dessas toda vez? Não é problemático?
    • Claro, você não pode escrever tal pilha de cada ajax, porque este tipo de código repetitivo deve ser encapsulado em uma função e chamado uniformemente.

Outras soluções:

Se você conhece muito bem sobre cookies, entenderá que o chamado cookie é essencialmente um headerparâmetro especial
e, como é apenas um parâmetro de cabeçalho, podemos simulá-lo e implementá-lo manualmente para concluir a operação de autenticação.

Na verdade, esta é 无Cookie模式outra solução correta. Os alunos interessados ​​​​podem descobrir isso no Baidu, então não entrarei em detalhes aqui.

5. Comparação de código

Para mostrar de forma mais intuitiva a diferença entre a arquitetura integrada de front-end e back-end e a arquitetura de separação de front-end e back-end, aqui está outro exemplo:

package com.pj.cases.up;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;

/** * Sa-Token 前后端分离模式示例 * * @author kong * @since 2022-10-17 */
@RestController
@RequestMapping("/NotCookie/")
public class NotCookieController {
   

	// 前后端一体模式的登录样例 ---- http://localhost:8081/NotCookie/doLogin?name=zhang&pwd=123456
	@RequestMapping("doLogin")
	public SaResult doLogin(String name, String pwd) {
   
		if("zhang".equals(name) && "123456".equals(pwd)) {
   
			// 会话登录 
			StpUtil.login(10001);
		    return SaResult.ok();
		}
		return SaResult.error("登录失败");
	}
	
	// 前后端分离模式的登录样例 ---- http://localhost:8081/NotCookie/doLogin2?name=zhang&pwd=123456
	@RequestMapping("doLogin2")
	public SaResult doLogin2(String name, String pwd) {
   
		
		if("zhang".equals(name) && "123456".equals(pwd)) {
   
			
			// 会话登录 
			StpUtil.login(10001);
			
			// 与常规登录不同点之处:这里需要把 Token 信息从响应体中返回到前端 
			SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
		    return SaResult.data(tokenInfo);
		}
		return SaResult.error("登录失败");
	}
	
}
  • Interface 1: O token será devolvido ao front-end no contexto do cookie e será enviado automaticamente pelo navegador sempre que solicitado, este modo é adequado para a arquitetura integrada de front-end e back-end.
  • Interface 2: O token será devolvido ao front-end no corpo da resposta e será armazenado manualmente pelo front-end e enviado manualmente a cada solicitação. Este modo é adequado para a arquitetura em que o front-end e o back-end são separados.

6. Personalize o prefixo enviado pelo Token

Em alguns sistemas, quando o front-end enviar o token, um prefixo fixo será adicionado na frente, por exemplo:

{
   
	"satoken": "Bearer xxxx-xxxx-xxxx-xxxx"
}

Neste momento, se o back-end não fizer nenhum processamento especial, a estrutura o considerará Bearer como parte do token e não poderá ler as informações do token normalmente, resultando em falha de autenticação.

Para fazer isso, precisamos adicionar a seguinte configuração ao yml:

sa-token: 
	# token前缀
	token-prefix: Bearer

Neste momento, o Sa-Token pode ser cortado ao ler o Token Bearere obtido com sucesso xxxx-xxxx-xxxx-xxxx.

ponto importante:

  1. Deve haver um espaço entre o prefixo do token e o valor do token.
  2. Uma vez configurado o prefixo do Token, Tokenele deve ser enviado com o prefixo, caso contrário o framework não conseguirá ler o Token.
  3. Como Cookieos caracteres de espaço não podem ser armazenados em , significa que após a configuração do prefixo do Token, o método de autenticação do Cookie será inválido. Neste momento, o Token só pode ser enviado para transmissão header.

7. Estilo de token personalizado

A estratégia de geração de token padrão do Sa-Token é o estilo uuid, que se parece com: 623368f0-ae5e-4475-a53f-93e4225f16ae.

Se você não estiver muito interessado neste estilo, também pode definir a geração de token para outros estilos.

Como configurá-lo? Você só precisa configurá-lo no arquivo de configuração yml sa-token.token-style=风格类型, que possui vários valores:

// 1. token-style=uuid —— uuid风格 (默认风格)
"623368f0-ae5e-4475-a53f-93e4225f16ae"

// 2. token-style=simple-uuid —— 同上,uuid风格, 只不过去掉了中划线
"6fd4221395024b5f87edd34bc3258ee8"

// 3. token-style=random-32 —— 随机32位字符串
"qEjyPsEA1Bkc9dr8YP6okFr5umCZNR6W"

// 4. token-style=random-六十四 —— 随机六十四位字符串
"v4ueNLEpPwMtmOPMBtOOeIQsvP8z9gkMgIVibTUVjkrNrlfra5CGwQkViDjO8jcc"

// 5. token-style=random-128 —— 随机128位字符串
"nojYPmcEtrFEaN0Otpssa8I8jpk8FO53UcMZkCP9qyoHaDbKS6dxoRPky9c6QlftQ0pdzxRGXsKZmUSrPeZBOD6kJFfmfgiRyUmYWcj4WU4SSP2ilakWN1HYnIuX0Olj"

// 6. token-style=tik —— tik风格
"gr_SwoIN0MC1ewxHX_vfCW3BothWDZMMtx__"

8. Estratégia de geração de token personalizado

Se você acha que nenhum dos estilos acima é o seu favorito, também pode personalizar a estratégia de geração de token para personalizar o estilo de geração de token.

Como fazer isso? Você só precisa reescrever o algoritmo SaStrategyda classe de estratégia createToken:

As etapas de referência são as seguintes:

1. SaTokenConfigureAdicione o código na classe de configuração:

@Configuration
public class SaTokenConfigure {
   
    /** * 重写 Sa-Token 框架内部算法策略 */
    @Autowired
    public void rewriteSaStrategy() {
   
    	// 重写 Token 生成策略 
    	SaStrategy.me.createToken = (loginId, loginType) -> {
   
    		return SaFoxUtil.getRandomString(60);	// 随机60位长度字符串
    	};
    }
}

2. Chame StpUtil.login(10001)o método novamente para efetuar login e observe o estilo do token gerado:

gfuPSwZsnUhwgz08GTCH4wOgasWtc3odP4HLwXJ7NDGOximTvT4OlW19zeLH

Referências

RustDesk 1.2: Usando o Flutter para reescrever a versão para desktop, suportando o suposto vazamento de arquitetura do modelo GPT-4 de Wayland: contém 1,8 trilhão de parâmetros, usando um modelo especialista misto (MoE) Musk anunciou o estabelecimento da empresa xAI deepin V23 adaptado com sucesso reivindicações do projeto WSL CentOS " Aberto a todos" Rust 1.71.0 Stable Release React Está tendo um momento Angular.js? Microsoft lança uma nova fonte padrão, Aptos, para substituir CalibriMicrosoft : Aumente os esforços para usar a versão Rust IntelliJ IDEA 2023.1.4 no Windows 11
{{o.name}}
{{m.name}}

Acho que você gosta

Origin my.oschina.net/u/3503445/blog/9869412
Recomendado
Clasificación