今天给大家分享个java中shiro的登录代码
package com.zdb.controller;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.alibaba.fastjson.JSON;
import com.zdb.entity.BaseOauth;
import com.zdb.entity.BaseOauthRecord;
import com.zdb.entity.BaseUser;
import com.zdb.service.LoginService;
import com.zdb.service.OauthService;
import com.zdb.shiro.ShiroSecurityHelper;
import com.zdb.util.ApplicationUtil;
import com.zdb.util.JsonCodeEnum;
import com.zdb.util.JsonDataUtil;
import com.zdb.util.ResultUtil;
@Controller
@RequestMapping("/login")
public class LoginController {
@Autowired
private LoginService loginService;
@Autowired
private OauthService oauthService;
@Autowired
private ShiroSecurityHelper shiroSecurityHelper;
/**************************************** 退出 ************************************************/
@ResponseBody
@RequestMapping(value="/retreat",produces = "application/json; charset=utf-8")
public String retreat(HttpServletRequest request){
String token = request.getHeader("token");
BaseOauth record = new BaseOauth();
record.setAccessToken(token);
List<BaseOauth> list = oauthService.selectByCondition(record);
if(list.size() >0){
record = list.get(0);
String sessionId = record.getSessionId();
Session session = shiroSecurityHelper.getSessionById(sessionId);
session.setAttribute("logout", "logout");
}
SecurityUtils.getSubject().logout();
return new JsonDataUtil(JsonCodeEnum.EC_20000, "退出成功").toJson();
}
/****************************************** 登录 ************************************************/
@RequestMapping(value="/login",produces = "application/json; charset=utf-8")
@ResponseBody
// @CrossOrigin(origins = {"*"})
public String backLogin(String loginName,String loginPwd,String client_id,String redirect_uri,HttpServletRequest request,HttpServletResponse response){
if (StringUtils.isEmpty(loginName) || StringUtils.isEmpty(loginPwd) || StringUtils.isEmpty(client_id))
{
return JSON.toJSONString(new JsonDataUtil(JsonCodeEnum.EC_20003, "传递的参数信息不全"));
}
//客户端判断
String judgePlatform = loginService.judgePlatform(client_id); //根据id查找访问凭证
//返回的字符串是否与比对的字符串error 匹配
if(judgePlatform.startsWith("error")){
return ResultUtil.getReturnResult(judgePlatform);
}
//登录信息判断
Object login = loginService.judgeLogin(loginName, loginPwd); //根据逻辑层返回的的是对象还是字符串如果是字符串就是登陆失败
if(login instanceof String){
return ResultUtil.getReturnResult(login);
}
BaseUser user = (BaseUser)login; //返回的是对象 把返回的对象强转成user对象。
//获取这个已登录对象的UserId
String userId = user.getUserId(); //获取这个已登录对象的UserId
Subject subject = SecurityUtils.getSubject(); //得到Subject
//登录
try {
String key= userId +"_"+ client_id; //根据userId和登录web端凭证
AuthenticationToken token = new UsernamePasswordToken(key, "1"); //得到创建用户名/密码身份验证Token(即用户身份/凭证)
subject.login(token); //登录,即身份验证
} catch (Exception e) {
e.printStackTrace(); //身份验证失败
return new JsonDataUtil(JsonCodeEnum.EC_20004, "登录失败,异常").toJson();
}
//保存登录信息
Session session = subject.getSession(); //可获取会话
session.setAttribute("userId", userId); //保存登录账号
session.setAttribute("client_id", client_id); //保存登录客户端
if("edcd4e6bad8a11e795f900219b160fec".equalsIgnoreCase(client_id)){
session.setTimeout(1000*60*60*24*30);
}
//创建访问凭证
String accessToken = createOauth(session, client_id, userId); //创建访问凭证
if(StringUtils.isEmpty(redirect_uri)){
return new JsonDataUtil(JsonCodeEnum.EC_20000, accessToken).toJson();
}else{
Map<String, String> queryParams = new HashMap<String, String>();
queryParams.put("token", accessToken); //返回一个token的accessToken
try {
WebUtils.issueRedirect(request, response, redirect_uri, queryParams );
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
/**
* 清除旧的访问信息,插入新的访问信息,
* @param session
* @param client_id
* @param userId
* @return 返回访问凭证
*/
private String createOauth(Session session, String client_id, String userId) {
//清除认证表中的凭证,客户端和账号,保存入历史表
BaseOauth record = new BaseOauth();
record.setAppId(client_id);
record.setUserId(userId);
List<BaseOauth> list = oauthService.selectByCondition(record); //根据Id查找凭证
Date recordTime = new Date();
for (BaseOauth oauth : list) {
String authId = oauth.getAuthId();
String sessionId = oauth.getSessionId();
oauthService.deleteOauthByPrimaryKey(authId); //删除凭证数据库表中数据根据凭证Id
//清除失效的session缓存
shiroSecurityHelper.deleteBySessionId(sessionId); //根据您sessionId删除redis失效的缓存
}
//清除权限缓存
String key= userId +"_"+ client_id;
shiroSecurityHelper.deletePermissionCache(key); //清除权限缓存
//插入新的访问凭证
String authId = ApplicationUtil.randomUUID(); //创建id
String accessToken = ApplicationUtil.randomUUID(); //随机生成accessToken
String sessionId = (String) session.getId();
BaseOauth oauth = new BaseOauth(authId, userId, client_id, accessToken, sessionId, recordTime);
oauthService.insertOauth(oauth); //存入凭证
BaseOauthRecord baseOauthRecord = new BaseOauthRecord(ApplicationUtil.randomUUID(), authId, userId, client_id, accessToken, sessionId, recordTime, recordTime);
oauthService.insertOauthRecord(baseOauthRecord); //存入凭证记录表
return accessToken;
}
下面是他里面所封装的一些方法
@Override
public String judgePlatform(String clientId) {
BasePlatform platform = new BasePlatform();
platform.setIsDeleted(false);
platform.setIsDisabled(false);
platform.setAppId(clientId);
List<BasePlatform> list = platformDao.selectByCondition(platform);
if(list.size()<1){
return ResultUtil.setErrorResult("登录客户端不能使用");
}
return ResultUtil.setSuccessResult("客户端可以使用");
}
@Override
public Object judgeLogin(String loginName, String loginPwd) {
//密码三次错误,出现验证码,10次错误今天不能登录
// 已登陆则 跳到首页
//10次是这个账号还是这个人被禁止登录
//是一个客户端还是所有客户端
//账号不存在
BaseLogin login = new BaseLogin();
login.setLoginName(loginName);
List<BaseLogin> logins = loginDao.selectByCondition(login); //查看账号是否存在
if(logins.size() < 1){ //存在查找数据大于1返回error
return ResultUtil.setErrorResult("login-error1");
}
login = logins.get(0); //账号存在而且没有重复账号 获取到返回 对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); //获取当前时间
String format = sdf.format(new Date()); //key为登录账号的loginId加当前登录时间
String key = login.getLoginId() + format;
String randomKey = login.getRandomKey(); //获得查出来的随机 盐
//根据密码 随机盐去跟数据库密码比对
if(!login.getLoginPwd().equals(PasswordUtil.encryptByPasswordAndSalt(loginPwd, randomKey))){ //经过解析查看密码是否匹配 密码不正正确走if逻辑
//密码是否正确
Long incr = redisService.incr(key); //根据login自动自增(根据key值存入redis中)
redisService.expire(key, 24*60*60); //设置key生存时间为24*60*60秒
if(incr>=10){ //如果自增的大于10等于10将禁止登录
return ResultUtil.setErrorResult("login-error6");
}else{
return ResultUtil.setErrorResult("login-error2/"+incr); //小于10时候给他提示密码错误还有还剩几次
}
}else if(login.getIsLocked()){ //查看登录的账号是否锁定 锁定也也抛出异常
//账号锁定
return ResultUtil.setErrorResult("login-error4");
}else if(login.getIsDeleted()){ //查看登录的账号是否删除 锁定也也抛出异常
//是否删除
return ResultUtil.setErrorResult("login-error5");
}
String value = redisService.get(key); //获取redis中村的自增值如果大于10 或者取出的值不为空 直接报错。当账号密码匹配不会走向redis存值得代码
if(value != null && Long.parseLong(value) >10){
return ResultUtil.setErrorResult("login-error6");
}
redisService.del(key); //清空redis寄存的值
String userId = login.getUserId(); //获取userId
BaseUser user = userDao.selectByPrimaryKey(userId);//根据userId查去user对象
if(user == null){ //如果查出为空接着抛异常
return ResultUtil.setErrorResult("login-error1");
}else if(user.getIsDeleted()){ //如果USER中是否删除接着抛异常
return ResultUtil.setErrorResult("login-error5");
}
return user; //最后返回user对象
}
我也不太懂 可能有点注释写的不太对 请大家多多指教。有错大家可以帮我指出来。谢谢