SpringBoot + Shiro + Mybatis-plus + Kaptcha + vue實(shí)現(xiàn)權(quán)限管理登錄功能
登錄功能
使用到的技術(shù)
-
shiro
-
Mybatis-plus
-
Springboot
-
kaptcha
參考優(yōu)秀博文
一個(gè)博主做的shiro筆記:https://www.guitu18.com/post/2019/07/26/43.html
引入依賴
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.7.0</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.1</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>2.3.2</version> </dependency> </dependencies>
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
配置shiro
package com.unclebb.zlgl.config; import com.unclebb.zlgl.utils.CustomRealm; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.mgt.DefaultSecurityManager; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.util.ThreadContext; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.HashMap; import java.util.Map; @Configuration public class ShiroConfig { @Bean public DefaultAdvisorAutoProxyCreator lifecycleBeanProcessor(){ DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); return defaultAdvisorAutoProxyCreator; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager){ AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager); return advisor; } @Bean public DefaultWebSecurityManager securityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); ThreadContext.bind(securityManager); return securityManager; } @Bean public CustomRealm myShiroRealm() { HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(); matcher.setHashAlgorithmName("md5"); matcher.setHashIterations(1); CustomRealm customRealm new CustomRealm(); customRealm.setCredentialsMatcher(matcher); return customRealm; } @Bean public ShiroFilterFactoryBean shiroFilter(DefaultSecurityManager securityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); return shiroFilterFactoryBean; } }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
83
-
84
-
85
-
86
-
87
-
88
-
89
-
90
-
91
-
92
-
93
-
94
-
95
-
96
配置swagger
package com.unclebb.zlgl.config; import com.google.common.base.Predicates; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 public class Swagger2Config { @Bean public Docket webApiConfig(){ return new Docket(DocumentationType.SWAGGER_2) .groupName("webApi") .apiInfo(webApiInfo()) .select() .paths(Predicates.and(PathSelectors.regex("/user/.*"))) .build(); } private ApiInfo webApiInfo(){ return new ApiInfoBuilder() .title("網(wǎng)站-API文檔") .description("本文檔描述了網(wǎng)站微服務(wù)接口定義") .version("1.0") .contact(new Contact("qy", "http://atguigu.com", "55317332@qq.com")) .build(); } }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
配置kaptcha
package com.unclebb.zlgl.config; import com.google.code.kaptcha.impl.DefaultKaptcha; import com.google.code.kaptcha.util.Config; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import java.util.Properties; @Component public class KaptchaConfig { @Bean public DefaultKaptcha getKaptcha(){ DefaultKaptcha dk = new DefaultKaptcha(); Properties properties = new Properties(); properties.setProperty("kaptcha.border", "yes"); properties.setProperty("kaptcha.border.color", "105,179,90"); properties.setProperty("kaptcha.textproducer.font.color", "red"); properties.setProperty("kaptcha.image.width", "110"); properties.setProperty("kaptcha.image.height", "40"); properties.setProperty("kaptcha.textproducer.font.size", "30"); properties.setProperty("kaptcha.session.key", "code"); properties.setProperty("kaptcha.textproducer.char.length", "4"); properties.setProperty("kaptcha.textproducer.font.names", "宋體,楷體,微軟雅黑"); Config config = new Config(properties); dk.setConfig(config); return dk; } }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
pojo
User
package com.unclebb.zlgl.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.util.Set; @Data @TableName(value = "user") public class User { @TableId(value = "id",type = IdType.AUTO) private int id; @TableField(value = "username") private String username; @TableField(value = "password") private String password; @TableField(exist = false) private Set<Role> rolesSet; private String salt; }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
Role
package com.unclebb.zlgl.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import lombok.Data; import java.util.Set; @Data public class Role { @TableId(value = "id",type = IdType.AUTO) private int id; @TableField(value = "user_name") private String userName; @TableField(value = "role_name") private String roleName; @TableField(exist = false) private Set<Permission> permissionSet; }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
Permission
package com.unclebb.zlgl.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import lombok.Data; @Data public class Permission { @TableId(value = "id",type = IdType.AUTO) private int id; @TableField(value = "role_name") private String roleName; @TableField(value = "permission_name") private String permissionName; }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
Mapper
基本格式:
package com.unclebb.zlgl.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.unclebb.zlgl.pojo.User; import org.apache.ibatis.annotations.Mapper; @Mapper public interface UserMapper extends BaseMapper<User> { }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
Service
Interface
LoginService
package com.unclebb.zlgl.service; import com.baomidou.mybatisplus.extension.service.IService; import com.unclebb.zlgl.pojo.User; import org.springframework.stereotype.Service; @Service public interface LoginService extends IService<User> { public User getByUsername(String username); }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
RoleService
package com.unclebb.zlgl.service; import com.baomidou.mybatisplus.extension.service.IService; import com.unclebb.zlgl.pojo.Role; import org.springframework.stereotype.Service; import java.util.List; @Service public interface RoleService extends IService<Role> { public List<Role> getRole(String userName); }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
PermissionService
package com.unclebb.zlgl.service; import com.baomidou.mybatisplus.extension.service.IService; import com.unclebb.zlgl.pojo.Permission; import org.springframework.stereotype.Service; import java.util.List; @Service public interface PermissionService extends IService<Permission> { public List<Permission> getPermissions(String roleName); }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
ServiceImpl
LoginServiceImpl
package com.unclebb.zlgl.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.unclebb.zlgl.mapper.UserMapper; import com.unclebb.zlgl.pojo.Role; import com.unclebb.zlgl.pojo.User; import com.unclebb.zlgl.service.LoginService; import com.unclebb.zlgl.service.PermissionService; import com.unclebb.zlgl.service.RoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashSet; import java.util.List; import java.util.Set; @Service public class LoginServiceImpl extends ServiceImpl<UserMapper, User> implements LoginService { @Autowired RoleService roleService; @Override public User getByUsername(String username) { QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("username",username); User user = this.getOne(wrapper); List<Role> roleList = roleService.getRole(user.getUsername()); user.setRolesSet(new HashSet<Role>(roleList)); return user; } }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
RoleServiceImpl
package com.unclebb.zlgl.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.unclebb.zlgl.mapper.RoleMapper; import com.unclebb.zlgl.pojo.Permission; import com.unclebb.zlgl.pojo.Role; import com.unclebb.zlgl.service.PermissionService; import com.unclebb.zlgl.service.RoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashSet; import java.util.List; import java.util.Set; @Service public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService { @Autowired PermissionService permissionService; @Override public List<Role> getRole(String userName) { QueryWrapper wrapper = new QueryWrapper(); wrapper.eq("user_name",userName); List<Role> roleList = this.list(wrapper); for (Role role:roleList){ List<Permission> permissions = permissionService.getPermissions(role.getRoleName()); role.setPermissionSet(new HashSet<Permission>(permissions)); } return roleList; } }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
PermissionServiceImpl
package com.unclebb.zlgl.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.unclebb.zlgl.mapper.PermissionMapper; import com.unclebb.zlgl.pojo.Permission; import com.unclebb.zlgl.pojo.User; import com.unclebb.zlgl.service.PermissionService; import org.springframework.stereotype.Service; import java.util.List; import java.util.Set; @Service public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService { @Override public List<Permission> getPermissions(String roleName) { QueryWrapper<Permission> wrapper = new QueryWrapper<>(); wrapper.eq("role_name",roleName); return this.list(wrapper); } }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
Controller
package com.unclebb.zlgl.controller; import com.unclebb.zlgl.pojo.Role; import com.unclebb.zlgl.pojo.User; import com.unclebb.zlgl.service.RoleService; import com.unclebb.zlgl.utils.Result; import io.swagger.annotations.ApiOperation; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpSession; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; @RestController public class LoginController { @Autowired RoleService roleService; @ApiOperation(value = "登錄接口") @RequestMapping("/user/login") public Result login(@RequestBody User user){ System.out.println("進(jìn)入/user/login API接口"); if (StringUtils.isEmpty(user.getUsername())||StringUtils.isEmpty(user.getPassword())){ return Result.fail("請(qǐng)輸入用戶名密碼"); } Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); Object sessionId = session.getId(); Map ret = new HashMap<String,Object>(); ret.put("token",sessionId); UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),user.getPassword()); try { subject.login(token); return Result.ok(ret); } catch (AuthenticationException e) { e.printStackTrace(); return Result.fail("用戶名密碼錯(cuò)誤"); } } @RequestMapping("/user/noauthority") public Result noauthority(){ return Result.fail("沒有權(quán)限"); } @RequestMapping("/user/demoSession") @ResponseBody public String demoSession(HttpSession session){ System.out.println("測(cè)試session"); Enumeration<String> names = session.getAttributeNames(); while (names.hasMoreElements()){ String name = names.nextElement(); Object value = session.getAttribute(name); System.out.println(name + " ------- "+ value); } return "session 取值"; } @RequestMapping("/user/demoSession2") @ResponseBody public String demoSession2(){ Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); System.out.println(session.getHost()); System.out.println(session.getId()); System.out.println(session.getLastAccessTime().getTime()); System.out.println(session.getTimeout()); System.out.println(session.getAttribute("test")); return "session 取值"; } @RequestMapping("/user/checkPermission") @ResponseBody public Result checkPermission(User user){ if (StringUtils.isEmpty(user.getUsername())||StringUtils.isEmpty(user.getPassword())){ return Result.fail("請(qǐng)輸入用戶名密碼"); } Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); session.setAttribute("test","test"); UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),user.getPassword()); token.setRememberMe(true); try { subject.login(token); } catch (AuthenticationException e) { e.printStackTrace(); return Result.fail("用戶名密碼錯(cuò)誤"); } try { subject.checkRole("admin"); return Result.ok("權(quán)限檢查成功"); } catch (AuthorizationException e) { e.printStackTrace(); return Result.fail("檢查權(quán)限失敗"); } } @RequestMapping("/user/checkRole") public Result checkRole(@RequestParam String token){ Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); List<Role> roleList = null; if (token.equals(session.getId().toString())){ String username = session.getAttribute("org.apache.shiro.subject.support.DefaultSubjectContext_PRINCIPALS_SESSION_KEY").toString(); System.out.println(username); roleList = roleService.getRole(username); } return Result.ok(roleList); } @RequestMapping("/user/testKaptcha") @ResponseBody public String TestKaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException { byte[] captcha = null; ByteArrayOutputStream out = new ByteArrayOutputStream(); try { String createText = defaultKaptcha.createText(); request.getSession().setAttribute("rightCode", createText); BufferedImage bi = defaultKaptcha.createImage(createText); ImageIO.write(bi, "jpg", out); } catch (Exception e) { response.sendError(HttpServletResponse.SC_NOT_FOUND); } captcha = out.toByteArray(); response.setHeader("Cache-Control", "no-store"); response.setHeader("Pragma", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("image/jpeg"); ServletOutputStream sout = response.getOutputStream(); sout.write(captcha); sout.flush(); sout.close(); return "測(cè)試Kaptcha"; } @RequestMapping(value = "/user/verifyKaptcha") public Result imgvrifyControllerDefaultKaptcha(HttpServletRequest request, HttpServletResponse response) { ModelAndView model = new ModelAndView(); String rightCode = (String) request.getSession().getAttribute("rightCode"); String tryCode = request.getParameter("tryCode"); System.out.println("rightCode:" + rightCode + " ———— tryCode:" + tryCode); if (!rightCode.equals(tryCode)) { model.addObject("info", "驗(yàn)證碼錯(cuò)誤,請(qǐng)?jiān)佥斠淮?"); model.setViewName("login"); return Result.fail("驗(yàn)證碼錯(cuò)誤"); } else { model.addObject("info", "登陸成功"); model.setViewName("index"); return Result.ok("驗(yàn)證成功"); } } @RequestMapping("/user/testShiroPermission") @RequiresPermissions("user:add") public Result TestShiroPermissions(){ System.out.println("訪問 TestShiroPermissions API"); Subject subject = SecurityUtils.getSubject(); String username = (String) subject.getPrincipal(); System.out.println(username); return Result.ok(username); } @RequestMapping("/user/logout") public Result logout(){ Subject subject = SecurityUtils.getSubject(); String username = (String) subject.getPrincipal(); subject.logout(); return Result.ok(username); } @RequestMapping("/user/TestRole") @RequiresRoles("admin") public Result TestRole(){ System.out.println("測(cè)試TestRole"); return Result.ok("測(cè)試Role"); } }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
83
-
84
-
85
-
86
-
87
-
88
-
89
-
90
-
91
-
92
-
93
-
94
-
95
-
96
-
97
-
98
-
99
-
100
-
101
-
102
-
103
-
104
-
105
-
106
-
107
-
108
-
109
-
110
-
111
-
112
-
113
-
114
-
115
-
116
-
117
-
118
-
119
-
120
-
121
-
122
-
123
-
124
-
125
-
126
-
127
-
128
-
129
-
130
-
131
-
132
-
133
-
134
-
135
-
136
-
137
-
138
-
139
-
140
-
141
-
142
-
143
-
144
-
145
-
146
-
147
-
148
-
149
-
150
-
151
-
152
-
153
-
154
-
155
-
156
-
157
-
158
-
159
-
160
-
161
-
162
-
163
-
164
-
165
-
166
-
167
-
168
-
169
-
170
-
171
-
172
-
173
-
174
-
175
-
176
-
177
-
178
-
179
-
180
-
181
-
182
-
183
-
184
-
185
-
186
-
187
-
188
-
189
-
190
-
191
-
192
-
193
-
194
-
195
-
196
-
197
-
198
-
199
-
200
-
201
-
202
-
203
-
204
-
205
-
206
-
207
-
208
-
209
-
210
-
211
-
212
-
213
-
214
-
215
-
216
-
217
-
218
-
219
-
220
-
221
-
222
-
223
-
224
-
225
-
226
-
227
-
228
-
229
-
230
-
231
-
232
-
233
-
234
-
235
-
236
-
237
-
238
-
239
-
240
-
241
-
242
-
243
-
244
-
245
-
246
-
247
-
248
-
249
-
250
-
251
-
252
-
253
-
254
-
255
-
256
-
257
-
258
-
259
-
260
-
261
-
262
-
263
-
264
-
265
-
266
-
267
-
268
-
269
-
270
-
271
-
272
-
273
-
274
-
275
-
276
-
277
-
278
-
279
util
Result
package com.unclebb.zlgl.utils; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data @ApiModel(value = "全局統(tǒng)一返回結(jié)果") public class Result<T> { @ApiModelProperty(value = "返回碼") private Integer code; @ApiModelProperty(value = "返回消息") private String message; @ApiModelProperty(value = "返回?cái)?shù)據(jù)") private T data; public Result(){} public static <T> Result<T> build(T data) { Result<T> result = new Result<T>(); if (data != null) result.setData(data); return result; } public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) { Result<T> result = build(body); result.setCode(resultCodeEnum.getCode()); result.setMessage(resultCodeEnum.getMessage()); return result; } public static<T> Result<T> ok(){ return Result.ok(null); } public static<T> Result<T> ok(T data){ Result<T> result = build(data); return build(data, ResultCodeEnum.SUCCESS); } public static<T> Result<T> fail(){ return Result.fail(null); } public static<T> Result<T> fail(T data){ Result<T> result = build(data); return build(data, ResultCodeEnum.FAIL); } public Result<T> message(String msg){ this.setMessage(msg); return this; } public Result<T> code(Integer code){ this.setCode(code); return this; } }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
ResultCode
package com.unclebb.zlgl.utils; import lombok.Getter; @Getter public enum ResultCodeEnum { SUCCESS(200,"成功"), FAIL(201, "失敗"), SERVICE_ERROR(202, "服務(wù)異常"), DATA_ERROR(204, "數(shù)據(jù)異常"), SIGN_ERROR(300, "簽名錯(cuò)誤"), PAY_PASSWORD_ERROR(401, "支付密碼錯(cuò)誤"), REPEAT_ERROR(402, "重復(fù)提交"), INVEST_AMMOUNT_MORE_ERROR(501, "出借金額已經(jīng)多余標(biāo)的金額"), RETURN_AMMOUNT_MORE_ERROR(502, "還款金額不正確"), PROJECT_AMMOUNT_ERROR(503, "標(biāo)的金額不一致") ; private Integer code; private String message; private ResultCodeEnum(Integer code, String message) { this.code = code; this.message = message; } }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
CustomRealm
package com.unclebb.zlgl.utils; import com.unclebb.zlgl.pojo.Permission; import com.unclebb.zlgl.pojo.Role; import com.unclebb.zlgl.pojo.User; import com.unclebb.zlgl.service.LoginService; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; public class CustomRealm extends AuthorizingRealm { @Autowired LoginService loginService; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String username = (String) principals.getPrimaryPrincipal(); User user = loginService.getByUsername(username); if (user == null){ return null; }else { SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); for (Role role : user.getRolesSet()){ simpleAuthorizationInfo.addRole(role.getRoleName()); for (Permission permission : role.getPermissionSet()){ simpleAuthorizationInfo.addStringPermission(permission.getPermissionName()); } } return simpleAuthorizationInfo; } } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = token.getPrincipal().toString(); User user = loginService.getByUsername(username); if (user == null){ return null; }else { SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,user.getPassword(),getName()); simpleAuthenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(user.getSalt())); return simpleAuthenticationInfo; } } }
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
前端代碼
前端我這里直接用了 開源的管理系統(tǒng)框架
附地址:
https://github.com/PanJiaChen/vue-admin-template
運(yùn)行截圖如下

完事兒只需要改一下它的 返回狀態(tài)碼校驗(yàn),配置下跨域就可以了
整合驗(yàn)證碼
驗(yàn)證碼部分包含兩個(gè)API接口
/user/testKaptcha 獲取驗(yàn)證碼信息
/user/verifyKaptcha 校驗(yàn)
其中獲取驗(yàn)證碼圖片信息相當(dāng)于請(qǐng)求靜態(tài)圖片資源,直接將驗(yàn)證碼圖片的src指向 該接口即可,前端源碼如下:
<el-image :src="kaptcha" @click="refreshCode()" alt="加載失敗" style="margin-left:10px;height:40px;margin-top:5px"> <div slot="placeholder" class="image-slot"> <i class="el-icon-loading"></i> </div> </el-image>
其中路徑定義為:
kaptcha:"http://localhost:8082/user/testKaptcha?t="+ new Date().getTime(),
后面加的時(shí)間參數(shù)是為了刷新url用的
前端的刷新函數(shù)就是將kaptcha重新賦值
refreshCode(){ console.log("測(cè)試切換驗(yàn)證碼") this.kaptcha = "http://localhost:8082/user/testKaptcha?t="+ new Date().getTime() console.log(this.kaptcha) },
登錄、權(quán)限校驗(yàn)、登出效果如下
登錄
登錄首先會(huì)驗(yàn)證 驗(yàn)證碼的正確性,登陸成功進(jìn)入主界面
驗(yàn)證碼錯(cuò)誤如下:

用戶名密碼錯(cuò)誤如下:

登陸成功后請(qǐng)求校驗(yàn)角色 校驗(yàn)成功
請(qǐng)求校驗(yàn)權(quán)限 校驗(yàn)成功
退出,執(zhí)行兩次,data為null
再次校驗(yàn)權(quán)限,報(bào)出異常
藍(lán)藍(lán)設(shè)計(jì)建立了UI設(shè)計(jì)分享群,每天會(huì)分享國(guó)內(nèi)外的一些優(yōu)秀設(shè)計(jì),如果有興趣的話,可以進(jìn)入一起成長(zhǎng)學(xué)習(xí),請(qǐng)掃碼藍(lán)小助,報(bào)下信息,藍(lán)小助會(huì)請(qǐng)您入群。歡迎您加入噢~~希望得到建議咨詢、商務(wù)合作,也請(qǐng)與我們聯(lián)系。

文章來源:csdn 作者:黑胡子大叔的小屋
分享此文一切功德,皆悉回向給文章原作者及眾讀者.
免責(zé)聲明:藍(lán)藍(lán)設(shè)計(jì)尊重原作者,文章的版權(quán)歸原作者。如涉及版權(quán)問題,請(qǐng)及時(shí)與我們?nèi)〉寐?lián)系,我們立即更正或刪除。
藍(lán)藍(lán)設(shè)計(jì)( www.yvirxh.cn )是一家專注而深入的界面設(shè)計(jì)公司,為期望卓越的國(guó)內(nèi)外企業(yè)提供卓越的UI界面設(shè)計(jì)、BS界面設(shè)計(jì) 、 cs界面設(shè)計(jì) 、 ipad界面設(shè)計(jì) 、 包裝設(shè)計(jì) 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計(jì)、 網(wǎng)站建設(shè) 、平面設(shè)計(jì)服務(wù)