前言:
在上一章 “SpringBoot 项目(若依脚手架)3”的基础上继续完成登录功能。
目录
二、重写 UserRealm 类中的 doGetAuthenticationInfo 方法(登录认证逻辑)
一、编写Controller 层代码
思路整理:
①、前台页面传 什么样的数据?
②、验证码 如何处理?
1)前端传输的数据 (login.js 文件中的代码片段)
2) 验证码
验证码生成时,需要将验证码放入 session 中。之前我们编写 “SysCaptchaController” 类的时候,已经将 验证码存入session
过滤器拦截请求, 验证码禁用 或不是表单提交 允许访问; 验证码开启 并且是表单提交需要 校验验证码是否正确
CaptchaValidateFilter 类中 重写 isAccessAllowed 方法
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
// 验证码禁用 或不是表单提交 允许访问
if( captchaEnabled == false || !"post".equals(httpServletRequest.getMethod().toLowerCase())){
return true;
}
return validateResponse(httpServletRequest, httpServletRequest.getParameter(ShiroConstants.CURRENT_VALIDATECODE));
}
public boolean validateResponse(HttpServletRequest httpServletRequest, String validatecode) {
Object obj = ShiroUtils.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
String code = String.valueOf(obj != null ? obj : "");
if(StringUtils.isEmpty(validatecode) || !validatecode.equalsIgnoreCase(code)){
return false;
}
return true;
}
CaptchaValidateFilter 类中用到 ShiroUtils 工具类中的 getSession 方法。这里顺便把 这个方法写一下
package com.ruoyi.framework.util;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
/**
* shiro 工具类
*
* @author liangcy
* @create 2019/10/14 - 11:32
*/
public class ShiroUtils {
public static Session getSession() {
return SecurityUtils.getSubject().getSession();
}
}
3)编写 通用的返回数据类 AjaxResult
package com.ruoyi.common.core.domain;
import com.ruoyi.common.utils.StringUtils;
import java.util.HashMap;
/**
* 操作消息提醒
*
* @author ruoyi
*/
public class AjaxResult extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
/**
* 状态码
*/
public static final String CODE_TAG = "code";
/**
* 返回内容
*/
public static final String MSG_TAG = "msg";
/**
* 数据对象
*/
public static final String DATA_TAG = "data";
/**
* 状态类型
*/
public enum Type {
/**
* 成功
*/
SUCCESS(0),
/**
* 警告
*/
WARN(301),
/**
* 错误
*/
ERROR(500);
private final int value;
Type(int value) {
this.value = value;
}
public int value() {
return this.value;
}
}
/**
* 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。
*/
public AjaxResult() {
}
/**
* 初始化一个新创建的 AjaxResult 对象
*
* @param type 状态类型
* @param msg 返回内容
*/
public AjaxResult(Type type, String msg) {
super.put(CODE_TAG, type.value);
super.put(MSG_TAG, msg);
}
/**
* 初始化一个新创建的 AjaxResult 对象
*
* @param type 状态类型
* @param msg 返回内容
* @param data 数据对象
*/
public AjaxResult(Type type, String msg, Object data) {
super.put(CODE_TAG, type.value);
super.put(MSG_TAG, msg);
if (StringUtils.isNotNull(data)) {
super.put(DATA_TAG, data);
}
}
/**
* 返回成功消息
*
* @return 成功消息
*/
public static AjaxResult success() {
return AjaxResult.success("操作成功");
}
/**
* 返回成功数据
*
* @return 成功消息
*/
public static AjaxResult success(Object data) {
return AjaxResult.success("操作成功", data);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @return 成功消息
*/
public static AjaxResult success(String msg) {
return AjaxResult.success(msg, null);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 成功消息
*/
public static AjaxResult success(String msg, Object data) {
return new AjaxResult(Type.SUCCESS, msg, data);
}
/**
* 返回警告消息
*
* @param msg 返回内容
* @return 警告消息
*/
public static AjaxResult warn(String msg) {
return AjaxResult.warn(msg, null);
}
/**
* 返回警告消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
public static AjaxResult warn(String msg, Object data) {
return new AjaxResult(Type.WARN, msg, data);
}
/**
* 返回错误消息
*
* @return
*/
public static AjaxResult error() {
return AjaxResult.error("操作失败");
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @return 警告消息
*/
public static AjaxResult error(String msg) {
return AjaxResult.error(msg, null);
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
public static AjaxResult error(String msg, Object data) {
return new AjaxResult(Type.ERROR, msg, data);
}
}
4)编写 Controller 的基类 BaseController
BaseController 类中有以下几点功能:
①、获取 request、response、session 对象的方法
②、 响应返回结果、返回成功、返回失败 的方法
③、页面跳转 的方法
④、抽取出通用的 分页方法(后面1-2章会再弄)
⑤、处理 前端传来的日期,转换成 date(后面再弄)
package com.ruoyi.common.core.controller;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.AjaxResult.Type;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sql.SqlUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.beans.PropertyEditorSupport;
import java.util.Date;
import java.util.List;
/**
* web层通用数据处理
*
* @author ruoyi
*/
@Slf4j
public class BaseController {
/**
* 获取request
*/
public HttpServletRequest getRequest()
{
return ServletUtils.getRequest();
}
/**
* 获取response
*/
public HttpServletResponse getResponse()
{
return ServletUtils.getResponse();
}
/**
* 获取session
*/
public HttpSession getSession()
{
return getRequest().getSession();
}
/**
* 响应返回结果
*
* @param rows 影响行数
* @return 操作结果
*/
protected AjaxResult toAjax(int rows)
{
return rows > 0 ? success() : error();
}
/**
* 响应返回结果
*
* @param result 结果
* @return 操作结果
*/
protected AjaxResult toAjax(boolean result)
{
return resul