springboot+mybatis+Oauth2 +vue 框架实现登录认证

1.最近在研究前后端分离项目,领导安排任务:使用Oauth2实现登录认证。因为第一次接触vue对里面的结构方法使用情况等不是很了解走了很多弯路。现在记录使用Oauth2实现登录认证,供大家参考.

2.首先了解了下Oauth2认证方式。

    Oauth2分为四种认证方式:授权码认证(authorization-code),隐藏式(implicit),密码式(password),凭证式(client credentials)。因为是前后端分离项目,所以使用最常用的方式,安全性能高的授权码方式。

关于Oauth认证此处不做介绍。可访问链家了解详情。

此链接是妧一峰老师的文章,讲的很详细,很受用。

http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html#support

3.下面正式记录vue+springboot+oauth的登录认证实现代码。因为自己经常去网上搜索时代码都是片段,对于新手来说还是很伤脑筋,所以此处直接贴整个代码。

springboot+mybatis+Oauth2 +vue 框架实现登录认证_第1张图片

login.vue界面:






4.前段拿到授权码去后台申请令牌获取资源

package com.ftsafe.rapido.system.controller;

import com.ftsafe.entity.RapidoOnlineUserEntity;
import com.ftsafe.rapido.common.annotation.Limit;
import com.ftsafe.rapido.common.authentication.JWTToken;
import com.ftsafe.rapido.common.authentication.JWTUtil;
import com.ftsafe.rapido.common.domain.ActiveUser;
import com.ftsafe.rapido.common.domain.RapidoConstant;
import com.ftsafe.rapido.common.domain.RapidoResponse;
import com.ftsafe.rapido.common.exception.RapidoException;
import com.ftsafe.rapido.common.properties.RapidoProperties;
import com.ftsafe.rapido.common.service.RedisService;
import com.ftsafe.rapido.common.utils.*;
import com.ftsafe.rapido.system.dao.LoginLogMapper;
import com.ftsafe.rapido.system.domain.LoginLog;
import com.ftsafe.rapido.system.domain.User;
import com.ftsafe.rapido.system.domain.UserConfig;
import com.ftsafe.rapido.system.manager.UserManager;
import com.ftsafe.rapido.system.service.LoginLogService;
import com.ftsafe.rapido.system.service.UserService;
import com.ftsafe.service.IRapidoBussinessService;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.apache.commons.lang3.StringUtils;
import org.apache.oltu.oauth2.client.OAuthClient;
import org.apache.oltu.oauth2.client.URLConnectionClient;
import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
import org.apache.oltu.oauth2.client.response.OAuthAccessTokenResponse;
import org.apache.oltu.oauth2.client.response.OAuthResourceResponse;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

@Validated
@RestController
public class LoginController {

    @Autowired
    private RedisService redisService;
    @Autowired
    private UserManager userManager;
    @Autowired
    private UserService userService;
    @Autowired
    private LoginLogService loginLogService;
    @Autowired
    private LoginLogMapper loginLogMapper;
    @Autowired
    private RapidoProperties properties;
    @Autowired
    private ObjectMapper mapper;
    
    @Reference(version = "${rapido.service.version}",
            application = "${dubbo.application.id}",
            retries = -1,
            interfaceClass = IRapidoBussinessService.class)
    private IRapidoBussinessService rapidoBussinessService;

    @PostMapping("/authLogin")
    @Limit(key = "authLogin", period = 60, count = 20, name = "登录认证接口", prefix = "limit")
    public RapidoResponse authLogin(
            @NotBlank(message = "{required}") String code, HttpServletRequest request) throws Exception {
    	final String errorMessage = "获取登录认证错误";
    	String userInfoStr = "";
    	String token = "";
    	//令牌
    	code = code.substring(code.indexOf("=")+1);
    	//设置请求令牌请求求信息
    	OAuthClientRequest accessTokenRequest = OAuthClientRequest.
    			tokenLocation(RapidoConstant.OAUTH_CLIENT_ACCESS_TOKEN).
    			setGrantType(GrantType.AUTHORIZATION_CODE).
    			setClientId(RapidoConstant.OAUTH_CLIENT_ID).
    			setClientSecret(RapidoConstant.OAUTH_CLIENT_SECRET).
    			setCode(code).
    			setRedirectURI(RapidoConstant.OAUTH_CLIENT_CALLBACK).
    			buildQueryMessage();
    			
    	OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
    	OAuthAccessTokenResponse oAuthResponse = oAuthClient.accessToken(accessTokenRequest, OAuth.HttpMethod.POST);
    	
    	//token令牌
    	token = oAuthResponse.getAccessToken();
    	Long expiresln = oAuthResponse.getExpiresIn();//过期时间
    	if(StringUtils.isEmpty(token)){
    		throw new RapidoException("获取令牌错误");
    	}
    	if(null == expiresln){
    		throw new RapidoException("令牌已过期或失效");
    	}
    	
    	//设置获取资源请求头信息
    	OAuthClientRequest userInfoRequest = new OAuthBearerClientRequest(RapidoConstant.OAUTH_CLIENT_USER_INFO).setAccessToken(token).buildQueryMessage();
    	userInfoRequest.setHeader("Authorization", "Bearer "+token);
    	
    	OAuthResourceResponse resourceResponse = oAuthClient.resource(userInfoRequest, OAuth.HttpMethod.GET, OAuthResourceResponse.class);
    		
    	userInfoStr = resourceResponse.getBody();
    	if(StringUtils.isEmpty(userInfoStr)){
    		throw new RapidoException("获取资源失败");
    	}
    	User user = JSONObject.parseObject(userInfoStr , User.class);// jsonStr 是String类型。
    	User auUser = this.userManager.getUser(user.getUsername());
    	auUser.setFullUserName(user.getFullUserName());
    	auUser.setEmail(user.getEmail());
    	  // 更新用户登录时间
        this.userService.updateLoginTime(auUser.getUsername());
        // 保存登录记录
        LoginLog loginLog = new LoginLog();
        loginLog.setUsername(user.getUsername());
        this.loginLogService.saveLoginLog(loginLog);
        
        //token有效期
    	Date du = new Date();
    	SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
    	long expiresa = du.getTime() + expiresln*1000;
    	
		//token加密
		token = RapidoUtil.encryptToken(JWTUtil.sign(user.getUsername(), "1de0f8a155afee2bf642bb57e38bc188"));
    	JWTToken tokenObj = new JWTToken(token,String.valueOf(df.format(expiresa)));
    	
    	//设置redis
		String userId = this.saveTokenToRedis(user, tokenObj, request);
		auUser.setId(userId);
	     
        Map userInfo = this.generateUserInfo(tokenObj, auUser);
    	return new RapidoResponse().message("认证成功").data(userInfo);
    }

}

你可能感兴趣的:(前端,vue)