Spring boot + LayIM + t-io 使用thyemleaf模板和Shiro实现登录
2017-11-25 11:27
846 查看
前言
在上一篇博客中已经实现了单聊和群聊的功能,并且做了详细讲解。不过上次还缺少灵活性,就是当前用户信息的问题,本篇中 t-io 的部分较少。并且为了实现快速登录,thymeleaf和Shiro我也只是做了简单使用,不过就做个学习记录吧。thymeleaf模板
网上的博客有很多,我就不在误人子弟了。简单的介绍下我使用的部分。首先我下载了基于layui的一个社区模板。下载地址:http://git.oschina.net/sentsin/fly,所以暂时就拿了他的布局和登录页面做登录功能。下载的模板里面有个common文件夹,里面已经提取出了 footer.html 和 header.html.我们先在resources文件夹下新建templates文件夹。然后新建 header,footer两个模板文件。分别代码如下:
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <body> <header th:fragment="header"> <div class="header"> <!--具体的header的HTML--> </div> </header> </body> </html>
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <body> <footer th:fragment="footer"> <div class="footer"> <!--具体的footer相关HTML--> </div> </footer> </body> </html>
然后在新建一个 layout 模板文件,引用上 header 和 footer。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.w3.org/1999/xhtml"> <head th:fragment="htmlhead"> <!--一些公共的JS,Css引用和meta等信息--> </head> <body> <!--替换成header的内容--> <div th:replace="fragments/header :: header">Header</div> <!--针对具体页面的内容部分--> <div layout:fragment="content" id="content" ></div> <!--替换成footer的内容--> <div th:replace="fragments/footer :: footer">footer</div> </body> </html>
比如,我把登录的页面内容套进去:
<!DOCTYPE html> <!--layout:decorator="layout" 这句代码可不能丢,要不然就没法渲染content内容了--> <html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.w3.org/1999/xhtml" layout:decorator="layout"> <head th:include="layout :: htmlhead" th:with="title='LayIM'"></head> <body> <scetion layout:fragment="content"> <div class="main layui-clear"> <!--登录窗体HTML--> </div> </scetion> </body> </html>
OK。页面布局就结束了,当然,我只是参照其他博客照猫画虎。目的就是快速搭建出架子,然后继续做核心部分。相关参考资料:https://www.cnblogs.com/ityouknow/p/5833560.html
运行效果如下:
Shiro
这个东东我也是用了很浅的一部分,不过在运行过程中,可以看到他已经做了很多授权,登录等相关的功能,这个我也就不多做介绍了。相关参考资料:http://blog.csdn.net/ityouknow/article/details/73836159
关于登录步骤不多说,无非登录验证然后跳转到首页。在这我只是介绍一下我所遇到的坑:
//我 x,加上static 还不行,还得具体的路径。之前加上 /static/css/** 不可以,所以直接改为访问路径 filterChainDefinitionMap.put("/css/**", "anon"); filterChainDefinitionMap.put("/js/**", "anon"); filterChainDefinitionMap.put("/images/**", "anon"); filterChainDefinitionMap.put("/html/**", "anon");
看我的注释就知道,刚开始我加了 static 路径下可以匿名访问,结果还是被拦截了,后来发现,需要写在浏览器中的路径(或者有其他原因?)
登录成功之后就会跳转到首页(index).如果登录不成功,配合 thymeleaf 语法显示不同的信息即可。这里呢我用了session存储错误信息,然后登录之后清空。登录部分代码如下:
/** * 代码参考:http://www.ityouknow.com/springboot/2017/06/26/springboot-shiro.html * */ @RequestMapping(value = "/login",method = RequestMethod.POST) public String login(HttpServletRequest request) throws Exception{ request.getSession().removeAttribute("login_msg"); // 登录失败从request中获取shiro处理的异常信息。 // shiroLoginFailure:就是shiro异常类的全类名. String exception = (String) request.getAttribute("shiroLoginFailure"); System.out.println("exception=" + exception); String msg = ""; if (exception != null) { if (UnknownAccountException.class.getName().equals(exception)) { msg = "account"; } else if (IncorrectCredentialsException.class.getName().equals(exception)) { msg = "pwd"; } else if ("kaptchaValidateFailed".equals(exception)) { msg = "code"; } else { msg = "other"; } request.getSession().setAttribute("login_msg",msg); } // 此方法不处理登录成功,由shiro进行处理 return "/account/login"; }
然后前端用到了 th:if 语法,判断错误消息是否显示。
<form th:action="@{/account/login}" th:method="post"> <!--其他代码--> <!--判断session中的login_msg是否==pwd--> <div class="layui-form-mid" th:if="${session.login_msg}=='pwd'"> <span style="color: #c00;">密码错误</span> </div> </form>
运行效果如下:
不细讲的原因是我自己用的比较粗浅,而且网上博客比较多,我这里只列举我用到了有坑的地方。或许坑也是我自己挖的。
登录后的业务处理
登录成功之后可以通过Shiro的Subject 拿到当前的用户ID,后来我以为在t-io服务端(LayimMsgHandler)也能拿到,后来发现too young too simple,因为他两个一个是端口8080,另外一个是端口8081,所以,Shiro的Session没有拿到。不过这个也有点类似SSO了, 后边打算用redis处理登录的用户ID问题。不过这里,我先用了生成token的方式,然后在连接服务器的时候,将token传过去,然后进行验证,在获取用户信息赋值给ContextUser,最后进行用户绑定和群组绑定。/** * 用 @Autowired 注解UserService 不起作用(原因我不是很清楚) * 解析客户端的token,获取用户信息转化为ContextUser对象 * 将ContextUser对象,以UserId为Key,ContextUser为value存入ChannelContext的Attribute中,方便后续使用当前用户信息 * 获取用户群组,遍历调用 Aio.bindGroup方法加入群组 * */ private HttpResponse handleHandshakeUserInfo(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) { UserService userService = (UserService) SpringUtil.getBean("userService"); //增加token验证方法 String path = httpRequest.getRequestLine().getPath(); String token = path.substring(1); String userId = UserToken.IsValid(token); if (userId == null) { //没有token 未授权 httpResponse.setStatus(HttpResponseStatus.C401); } else { //解析token LayimContextUserInfo userInfo = userService.getContextUserInfo(Long.parseLong(userId)); if (userInfo == null) { //没有找到用户 httpResponse.setStatus(HttpResponseStatus.C404); } else { channelContext.setAttribute(userId, userInfo.getContextUser()); //绑定用户ID Aio.bindUser(channelContext, userId); //绑定用户群组 List<String> groupIds = userInfo.getGroupIds(); //绑定用户群信息 if (groupIds != null) { groupIds.forEach((String groupId) -> Aio.bindGroup(channelContext, groupId)); } } } return httpResponse; }
UserToken.IsValid就是验证token的合法性。通过url传过来。所以,前端稍微改一下,还要在UserController中增加一个生成token的接口。那么连接websocket服务器的时候就要先获取token。
$.get('/layim/token',function (res) { if(res.code>0) { return; } socket.config({ log:true, server:'ws://127.0.0.1:8888/'+res.data }); //其他监听代码 })
所以在运行时候是酱紫的:
如果不加token或者token无效的话,会返回401
总结
本文内容零零散散的介绍了一些,主要是完成了登录的流程和服务端的对接。按理说,web端应该是和 websocket端分开的,只不过当时一心想合并到一起去。后来开发过程中发现完全是相当于两个项目之间的一些交互。当然这些都是我的个人理解。在后续的博客中将会讲到LayIM的一些常用接口的使用和t-io的一些接口的探索使用。比如,用户在线情况,各种提示等。拜~
代码已经同步到:https://github.com/fanpan26/SpringBootLayIM
相关文章推荐
- springboot+shiro实现登录系数限定,thymeleaf中使用shiro标签
- Spring boot + LayIM + t-io 单聊群聊的实现
- Spring Boot使用Netty SocketIO实现WebIM功能
- 本文主要介绍使用SpringBoot与shiro实现基于数据库的细粒度动态权限管理系统实例。
- 使用manven+hibernate+spring+shiro登录验证实现简单增删改查
- SpringBoot整合Shiro实现登录认证的方法
- spring boot 使用拦截器 实现 用户登录拦截
- springboot+shiro+cas实现单点登录之cas server搭建
- SpringBoot/SpringMVC整合Shiro(一):实现登录与注册(MD5加盐加密)
- Spring Boot Shiro 权限信息缓存处理,记住我,thymleaf使用shiro标签
- Spring Boot使用HandlerInterceptorAdapter和WebMvcConfigurerAdapter实现原始的登录验证
- 七、spring boot 1.5.4 集成shiro+cas,实现单点登录和权限控制
- springboot整合shiro登录失败次数限制功能的实现代码
- 用shiro+springboot+mybatis实现禁止账号重复登录
- SpringBoot使用Shiro验证登录笔记
- 简单两步快速实现shiro的配置和使用,包含登录验证、角色验证、权限验证以及shiro登录注销流程(基于spring的方式,使用maven构建)
- Spring boot + LayIM + t-io 实现文件上传、 监听用户状态的实例代码
- springboot系列(一):初次使用与登录验证实现
- Spring Boot Shiro 权限信息缓存处理,记住我,thymleaf使用shiro标签
- springboot+shiro+cas实现单点登录之shiro端搭建