什么是Token Store
在Web开发中,Token Store 通常用于存储用户身份验证令牌(Tokens),例如 JSON Web Tokens (JWT) 或其他形式的令牌。这些令牌可以用于验证用户身份,实现用户会话管理以及访问控制。
一种简单的Token Store示例,使用Node.js和Express框架以及一个基于内存的Token存储方式:
const express = require('express'); const jwt = require('jsonwebtoken'); const app = express(); app.use(express.json()); // In-memory Token Store const tokenStore = {}; // Secret key for JWT (replace with a strong, secret key in production) const secretKey = 'your_secret_key'; // Middleware to verify JWT function verifyToken(req, res, next) { const token = req.headers.authorization; if (!token) { return res.status(403).json({ message: 'No token provided' }); } jwt.verify(token, secretKey, (err, decoded) => { if (err) { return res.status(401).json({ message: 'Failed to authenticate token' }); } req.user = decoded; next(); }); } // Endpoint to generate and return a JWT app.post('/login', (req, res) => { const { username, password } = req.body; // Authenticate user (replace with your actual authentication logic) // For simplicity, assume any username and password combination is valid const user = { username, role: 'user' }; // Generate a JWT const token = jwt.sign(user, secretKey, { expiresIn: '1h' }); // Store the token in memory tokenStore[token] = user; res.json({ token }); }); // Protected endpoint that requires a valid JWT for access app.get('/protected', verifyToken, (req, res) => { res.json({ message: 'This is a protected endpoint', user: req.user }); }); // Start the server const port = 3000; app.listen(port, () => { console.log(`Server is running on http://localhost:${port}`); });
Spring Security 提供了几个常见的
TokenStore
实现,包括内存中存储、JDBC 数据库存储和基于 JWT(JSON Web Token)的存储。下面将分别介绍这三种实现方式,并提供基本的代码示例。
1. 内存中存储(In-Memory)
@Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Bean public TokenStore inMemoryTokenStore() { return new InMemoryTokenStore(); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients .inMemory() .withClient("client") .secret("{noop}secret") // 使用 "{noop}" 表示不加密 .authorizedGrantTypes("password", "authorization_code", "refresh_token") .scopes("read", "write") .accessTokenValiditySeconds(3600) .refreshTokenValiditySeconds(86400); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints .tokenStore(inMemoryTokenStore()) .authenticationManager(authenticationManager); } }
2. JDBC 数据库存储
@Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private DataSource dataSource; @Bean public TokenStore jdbcTokenStore() { return new JdbcTokenStore(dataSource); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients .jdbc(dataSource); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints .tokenStore(jdbcTokenStore()) .authenticationManager(authenticationManager); } }
3. 基于 JWT 的存储
@Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Value("${security.jwt.client-id}") private String clientId; @Value("${security.jwt.client-secret}") private String clientSecret; @Value("${security.jwt.grant-type}") private String grantType; @Value("${security.jwt.scope-read}") private String scopeRead; @Value("${security.jwt.scope-write}") private String scopeWrite; @Value("${security.jwt.resource-ids}") private String resourceIds; @Bean public TokenStore jwtTokenStore() { return new JwtTokenStore(jwtAccessTokenConverter()); } @Bean public JwtAccessTokenConverter jwtAccessTokenConverter() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setSigningKey("secret"); return converter; } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients .inMemory() .withClient(clientId) .secret("{noop}" + clientSecret) .authorizedGrantTypes(grantType) .scopes(scopeRead, scopeWrite) .resourceIds(resourceIds); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints .tokenStore(jwtTokenStore()) .accessTokenConverter(jwtAccessTokenConverter()) .authenticationManager(authenticationManager); } }
小结
我们介绍了Spring Security中三种不同的Token Store实现方式。具体包括内存中存储、JDBC数据库存储和基于JWT的存储。每个实现方式都涉及到授权服务器的配置,用于管理和验证令牌,以及客户端详情的配置。
大家点赞、收藏、关注、评论啦!谢谢三连哦!