溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring Boot+JWT+Shiro+MybatisPlus怎么實現Restful快速開發后端腳手架

發布時間:2021-11-15 15:36:31 來源:億速云 閱讀:163 作者:柒染 欄目:大數據

Spring Boot+JWT+Shiro+MybatisPlus怎么實現Restful快速開發后端腳手架

在現代Web開發中,快速搭建一個高效、安全的后端服務是每個開發者的追求。Spring Boot作為Java生態中最流行的框架之一,以其簡潔的配置和強大的功能贏得了廣泛的青睞。結合JWT(JSON Web Token)、Shiro(Apache Shiro)和MybatisPlus,我們可以快速構建一個功能完善的后端腳手架。本文將詳細介紹如何使用這些技術棧實現一個Restful風格的后端服務。

1. 項目初始化

首先,我們需要創建一個Spring Boot項目??梢允褂肧pring Initializr來快速生成項目骨架。選擇以下依賴:

  • Spring Web
  • MyBatis Plus
  • Spring Security
  • Shiro
  • JWT
  • Lombok

生成項目后,導入到IDE中,確保項目結構如下:

src
├── main
│   ├── java
│   │   └── com
│   │       └── example
│   │           └── demo
│   │               ├── config
│   │               ├── controller
│   │               ├── entity
│   │               ├── mapper
│   │               ├── service
│   │               └── DemoApplication.java
│   └── resources
│       ├── application.yml
│       └── mapper
└── test
    └── java
        └── com
            └── example
                └── demo

2. 配置MybatisPlus

MybatisPlus是Mybatis的增強工具,提供了許多便捷的功能。首先,我們需要在application.yml中配置數據庫連接和MybatisPlus的相關設置:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=UTC
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.example.demo.entity
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

接下來,創建一個實體類User

@Data
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String username;
    private String password;
    private String role;
}

然后,創建Mapper接口UserMapper

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

3. 集成Shiro和JWT

Shiro是一個強大的安全框架,而JWT是一種輕量級的身份驗證機制。我們將結合兩者來實現用戶認證和授權。

首先,添加Shiro和JWT的依賴:

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.7.1</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

接下來,創建一個JWT工具類JwtUtil

public class JwtUtil {
    private static final String SECRET_KEY = "your-secret-key";

    public static String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 1天
                .signWith(SignatureAlgorithm.HS512, SECRET_KEY)
                .compact();
    }

    public static String getUsernameFromToken(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody()
                .getSubject();
    }
}

然后,配置Shiro的RealmFilter

public class JwtRealm extends AuthorizingRealm {
    @Autowired
    private UserMapper userMapper;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = (String) principals.getPrimaryPrincipal();
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRole(user.getRole());
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String jwtToken = (String) token.getPrincipal();
        String username = JwtUtil.getUsernameFromToken(jwtToken);
        if (username == null) {
            throw new AuthenticationException("Invalid token");
        }
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        if (user == null) {
            throw new AuthenticationException("User not found");
        }
        return new SimpleAuthenticationInfo(username, jwtToken, getName());
    }
}
public class JwtFilter extends AuthenticatingFilter {
    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String token = httpRequest.getHeader("Authorization");
        if (token == null || !token.startsWith("Bearer ")) {
            return null;
        }
        return new JwtToken(token.substring(7));
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        AuthenticationToken token = createToken(request, response);
        if (token == null) {
            return true;
        }
        try {
            getSubject(request, response).login(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

最后,配置Shiro的SecurityManagerFilter

@Configuration
public class ShiroConfig {
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);

        Map<String, Filter> filters = new HashMap<>();
        filters.put("jwt", new JwtFilter());
        factoryBean.setFilters(filters);

        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/**", "jwt");
        factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return factoryBean;
    }

    @Bean
    public SecurityManager securityManager(JwtRealm jwtRealm) {
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        securityManager.setRealm(jwtRealm);
        return securityManager;
    }

    @Bean
    public JwtRealm jwtRealm() {
        return new JwtRealm();
    }
}

4. 實現Restful API

現在,我們可以實現一些Restful API來測試我們的腳手架。首先,創建一個UserController

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserMapper userMapper;

    @PostMapping("/login")
    public String login(@RequestParam String username, @RequestParam String password) {
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        if (user != null && user.getPassword().equals(password)) {
            return JwtUtil.generateToken(username);
        }
        throw new RuntimeException("Invalid username or password");
    }

    @GetMapping("/info")
    public User info(@RequestHeader("Authorization") String token) {
        String username = JwtUtil.getUsernameFromToken(token.substring(7));
        return userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
    }
}

5. 測試

啟動項目后,可以使用Postman或其他工具測試API。首先,調用/user/login接口獲取JWT令牌,然后在請求其他接口時在Header中添加Authorization: Bearer <token>。

6. 總結

通過Spring Boot、JWT、Shiro和MybatisPlus的結合,我們快速搭建了一個功能完善的后端腳手架。這個腳手架不僅支持用戶認證和授權,還提供了Restful風格的API接口。希望本文能幫助你快速上手這些技術,并在實際項目中應用它們。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女