黑狐家游戏

oauth2.0 jwt单点登录,jwt单设备登录

欧气 4 0

标题:基于 OAuth2.0 和 JWT 的单设备登录实现

一、引言

在当今的互联网应用中,用户登录是一个至关重要的环节,为了提供更好的用户体验和安全性,单点登录(Single Sign-On,SSO)技术应运而生,OAuth2.0 和 JSON Web Token(JWT)是两种常用的技术,它们可以帮助实现安全、高效的单点登录,本文将介绍如何使用 OAuth2.0 和 JWT 实现单设备登录,并提供相应的代码示例。

二、OAuth2.0 简介

OAuth2.0 是一种授权框架,它允许用户授权第三方应用访问他们的资源,而无需共享用户名和密码,OAuth2.0 定义了四种授权类型:授权码授权、简化授权、密码模式和客户端凭证模式,我们将使用授权码授权类型。

三、JWT 简介

JWT 是一种基于 JSON 的轻量级令牌,它可以在不同的系统之间安全地传输信息,JWT 由三部分组成:头部、负载和签名,头部包含令牌的类型和加密算法等信息,负载包含用户的身份信息和其他自定义信息,签名用于验证令牌的完整性和真实性。

四、单设备登录流程

单设备登录的流程如下:

1、用户访问客户端应用,客户端应用引导用户登录到授权服务器。

2、用户在授权服务器上输入用户名和密码,授权服务器验证用户的身份,并生成一个访问令牌和一个刷新令牌。

3、授权服务器将访问令牌和刷新令牌返回给客户端应用,并将用户重定向到客户端应用指定的回调 URL。

4、客户端应用将访问令牌和刷新令牌存储在本地,并使用访问令牌向资源服务器请求资源。

5、资源服务器验证访问令牌的有效性,并返回相应的资源给客户端应用。

6、如果访问令牌过期,客户端应用可以使用刷新令牌向授权服务器请求新的访问令牌。

五、代码实现

以下是一个使用 Spring Boot 和 Spring Security 实现的基于 OAuth2.0 和 JWT 的单设备登录示例:

1、引入依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
</dependency>

2、配置 OAuth2.0 服务器:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private DataSource dataSource;
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
             .tokenStore(tokenStore())
             .authenticationManager(authenticationManager());
    }
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients
             .jdbc(dataSource)
             .withClient("client_id")
             .secret("client_secret")
             .authorizedGrantTypes("authorization_code")
             .scopes("read", "write")
             .autoApprove(true);
    }
    @Bean
    public TokenStore tokenStore() {
        return new JdbcTokenStore(dataSource);
    }
    @Bean
    public AuthenticationManager authenticationManager() throws Exception {
        return authenticationManagerBean();
    }
}

3、配置资源服务器:

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
             .authorizeRequests()
             .antMatchers("/api/**").access("#oauth2.hasScope('read')")
             .and()
             .oauth2ResourceServer()
             .jwt();
    }
}

4、实现用户服务:

@Service
public class UserService {
    public User getUserById(Long id) {
        // 根据用户 ID 查询用户信息
        return new User(id, "user_name", "user_password");
    }
}

5、实现 JWT 令牌生成器:

@Component
public class JwtTokenGenerator {
    private final SecretKey secretKey;
    public JwtTokenGenerator() {
        byte[] keyBytes = Base64.getDecoder().decode("secret_key");
        secretKey = new SecretKeySpec(keyBytes, SignatureAlgorithm.HS256.getJcaName());
    }
    public String generateToken(User user) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("user_id", user.getId());
        claims.put("user_name", user.getUserName());
        return Jwts.builder()
             .setClaims(claims)
             .signWith(secretKey)
             .compact();
    }
}

6、实现登录控制器:

@Controller
public class LoginController {
    @Autowired
    private UserService userService;
    @Autowired
    private JwtTokenGenerator jwtTokenGenerator;
    @GetMapping("/login")
    public String login() {
        return "login";
    }
    @PostMapping("/login")
    public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model) {
        User user = userService.getUserById(1L);
        if (user.getPassword().equals(password)) {
            String token = jwtTokenGenerator.generateToken(user);
            model.addAttribute("token", token);
            return "redirect:/api/resources";
        } else {
            model.addAttribute("error", "Invalid username or password");
            return "login";
        }
    }
}

7、实现资源控制器:

@RestController
@RequestMapping("/api/resources")
public class ResourceController {
    @GetMapping
    public String getResources(@RequestHeader("Authorization") String authorization) {
        String token = authorization.substring("Bearer ".length());
        Claims claims = Jwts.parser()
             .setSigningKey(secretKey)
             .parseClaimsJws(token)
             .getBody();
        Long userId = (Long) claims.get("user_id");
        String userName = (String) claims.get("user_name");
        return "User ID: " + userId + ", User Name: " + userName;
    }
}

六、总结

本文介绍了如何使用 OAuth2.0 和 JWT 实现单设备登录,通过使用 OAuth2.0,我们可以实现安全的授权和访问控制,而通过使用 JWT,我们可以在不同的系统之间安全地传输用户身份信息,希望本文对你有所帮助。

标签: #OAuth2.0 #JWT #单点登录 #单设备登录

黑狐家游戏
  • 评论列表

留言评论