以通过微信开放平台扫码登录为例
一、网站应用微信登录
用户通过扫码获取微信授权,返回openid信息
1、Controller层
@Controller
@RequestMapping("/wechat")
@Slf4j
public class WechatController {
@Autowired
private WxMpService wxMpService;
@Autowired
private WxMpService wxOpenService;
@Autowired
private ProjectUrlConfig projectUrlConfig;
/**
* 微信开放平台授权登录
*
* @param returnUrl
* @return
*/
//访问:http://127.0.0.1:8080/sell/wechat/qrAuthorize?returnUrl=http://www.imooc.com
//访问:http://t238997p11.qicp.vip/sell/wechat/qrAuthorize?returnUrl=http://t238997p11.qicp.vip/sell/seller/login
@GetMapping("/qrAuthorize")
public String qrAuthorize(@RequestParam("returnUrl") String returnUrl){
// String url = "http://t238997p11.qicp.vip/sell/wechat/qrUserInfo";
String url = projectUrlConfig.getWechatOpenAuthorize() + "/sell/wechat/qrUserInfo";
String redirectUrl = wxOpenService.buildQrConnectUrl(url,WxConsts.QrConnectScope.SNSAPI_LOGIN, URLEncoder.encode(returnUrl));
log.info("微信开放平台授权获取code,redirectUrl={}",redirectUrl);
return "redirect:" + redirectUrl;
}
/**
* 微信开放平台扫码获取openid
*
* @param code
* @param returnUrl
* @return
*/
@GetMapping("/qrUserInfo")
public String qrUserInfo(@RequestParam("code") String code,
@RequestParam("state") String returnUrl){
WxMpOAuth2AccessToken wxMpOAuth2AccessToken = new WxMpOAuth2AccessToken();
try {
wxMpOAuth2AccessToken = wxOpenService.oauth2getAccessToken(code);
} catch (WxErrorException e) {
log.info("[微信网页授权] {}",e);
throw new SellException(ResultEnum.WECHAT_MP_ERROR.getCode(),e.getError().getErrorMsg());
}
//获取openid
String openId = wxMpOAuth2AccessToken.getOpenId();
return "redirect:" + returnUrl+"?openid=" + openId;
}
2、application.yml文件
wechat:
myAppId: wx085c556cb1d22b1f #微信公众平台测试账号
myAppSecret: 306416745e957da269b33ac134df28fd #微信公众平台账号秘钥
openAppId: wx277996c4d2772104 #微信开放平台账号
openAppSecret: b5e4052a545c997a6f98fe0579860bd1 #微信开放平台账号秘钥
project:
wechatMpAuthorize: http://t238997p11.qicp.vip #微信公众平台授权访问基础地址(授权域名)
wechatOpenAuthorize: http://testdev.tunnel.qydev.com #微信开放平台授权访问基础地址(授权域名)
sell: http://t238997p11.qicp.vip #项目地址
3、WechatAccountConfig
@Data
@Component
@ConfigurationProperties(prefix = "wechat")
public class WechatAccountConfig {
/*公众平台appid*/
private String myAppId;
/* 公众平台秘钥*/
private String myAppSecret;
/*开放平台id*/
private String openAppId;
/*开放平台秘钥*/
private String openAppSecret;
}
4、WechatMpConfig:微信公众平台配置
@Component
public class WechatMpConfig {
@Autowired
private WechatAccountConfig accountConfig;
@Bean
public WxMpService wxMpService(){
WxMpService wxMpService = new WxMpServiceImpl();
wxMpService.setWxMpConfigStorage(wxMpConfigStorage());
return wxMpService;
}
@Bean
public WxMpConfigStorage wxMpConfigStorage(){
WxMpInMemoryConfigStorage wxMpConfigStorage = new WxMpInMemoryConfigStorage();
wxMpConfigStorage.setAppId(accountConfig.getMyAppId());
wxMpConfigStorage.setSecret(accountConfig.getMyAppSecret());
return wxMpConfigStorage;
}
}
5、WechatOpenConfig微信开放平台配置
@Component
public class WechatOpenConfig {
@Autowired
private WechatAccountConfig accountConfig;
@Bean
public WxMpService wxOpenService() {
WxMpService wxOpenService = new WxMpServiceImpl();
wxOpenService.setWxMpConfigStorage(wxOpenConfigStorage());
return wxOpenService;
}
@Bean
public WxMpConfigStorage wxOpenConfigStorage() {
WxMpInMemoryConfigStorage wxMpInMemoryConfigStorage = new WxMpInMemoryConfigStorage();
wxMpInMemoryConfigStorage.setAppId(accountConfig.getOpenAppId());
wxMpInMemoryConfigStorage.setSecret(accountConfig.getOpenAppSecret());
return wxMpInMemoryConfigStorage;
}
}
6、WxConsts:微信常量
public final class WxConstants {
//授权
public static final String AUTH_BASE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?";
//获取token
public static final String ACCESS_TOKEN_BASE_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?";
//获取用户信息
public static final String INFO_BASE_URL = "https://api.weixin.qq.com/sns/userinfo?";
//回调
public static final String REDIRECT_URL = "http://t238997p11.qicp.vip/sell/weixin/auth";
//允许的范围
public static final String SCOPE = "snsapi_userinfo";
//token
public static final String TOKEN = "zhangxiaoxin";
private WxConstants(){}
}
7、ProjectUrlConfig类
@Data
@ConfigurationProperties(prefix = "project")
@Component
public class ProjectUrlConfig {
/**
* 微信公众平台授权url
*/
public String wechatMpAuthorize;
/**
* 微信开放平台授权url
*/
public String wechatOpenAuthorize;
/**
* 点餐系统
*/
public String sell;
}
3、配置文件
4、结果:访问:http://127.0.0.1:8080/sell/wechat/qrAuthorize?returnUrl=http://www.imooc.com
会跳转到http://www.imooc.com?openid=xxxxxxxxxxxxxxx
这样就获取到了openid
二、登录登出
只有openid匹配了数据库中的openid才可登录!!!!如果第一步没有实现,直接从第二步开始也可以
1、Controller层
登录:将openid设置进redis及cookie中
登出:清除redis和cookie中的内容
@Controller
@RequestMapping("/seller")
public class SellerUserController {
@Autowired
private SellerService sellerService;
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private ProjectUrlConfig projectUrlConfig;
@GetMapping("/login")
public ModelAndView login(@RequestParam(value = "openid",defaultValue = "o7TyS59g2pb-fJy6o93QidfURK1k") String openid,HttpServletResponse response,Map<String,Object> map){
//由于没有微信账号,不支持扫码登陆的功能,所以也没办法获取到openid,故在此给一个默认值
//1.openid去和数据库的匹配
SellerInfo sellerInfo = sellerService.findSellerInfoByOpenid(openid);
if (sellerInfo == null) {
map.put("msg", ResultEnum.LOGIN_FAIL.getMsg());
map.put("url","/sell/seller/order/list");
return new ModelAndView("common/error",map);
}
//2、设置token到redis
String token = UUID.randomUUID().toString();
Integer expire = RedisConstant.EXPIRE;
//String.format(RedisConstant.TOKEN_PREFTX,token):redis的key
//openid:value
//expire:过期时间
//TimeUnit.DAYS.SECONDS:时间单位
redisTemplate.opsForValue().set(String.format(RedisConstant.TOKEN_PREFTX,token),openid,expire, TimeUnit.DAYS.SECONDS);
//3、设置token到cookie
/*Cookie cookie = new Cookie("token",token);
cookie.setPath("/");
cookie.setMaxAge(7200);
response.addCookie(cookie);*/
//封装成了工具类,使用工具类中的方法
CookieUtil.set(response, CookieConstant.TOKEN,token,expire);
return new ModelAndView("redirect:" + projectUrlConfig.getSell() + "/sell/seller/order/list");
}
@GetMapping("/logout")
public ModelAndView logout(HttpServletRequest request,HttpServletResponse response,
Map<String,Object> map){
//1、从cookie里面查询
Cookie cookie = CookieUtil.get(request, CookieConstant.TOKEN);
if (cookie != null) {
//2、清除redis
redisTemplate.opsForValue().getOperations().delete(String.format(RedisConstant.TOKEN_PREFTX,cookie.getValue()));
//3、清除cookie
CookieUtil.set(response,CookieConstant.TOKEN,null,0);
}
map.put("msg",ResultEnum.LOGOUT_SCUUESS.getMsg());
map.put("url","/sell/seller/order/list");
return new ModelAndView("common/success",map);
}
}
2、相关类
(1)RedisConstant
public interface RedisConstant {
String TOKEN_PREFTX = "token_%s";
Integer EXPIRE = 7200; //2小时
}
(2)CookieConstant
public interface CookieConstant {
String TOKEN = "token";
Integer EXPIRE = 7200;
}
(3)CookieUtil
public class CookieUtil {
/**
* 设置
* @param response
* @param name
* @param value
* @param maxAge
*/
public static void set(HttpServletResponse response,
String name,
String value,
int maxAge) {
Cookie cookie = new Cookie(name, value);
cookie.setPath("/");
cookie.setMaxAge(maxAge);
response.addCookie(cookie);
}
/**
* 获取cookie
* @param request
* @param name
* @return
*/
public static Cookie get(HttpServletRequest request,
String name) {
Map<String, Cookie> cookieMap = readCookieMap(request);
if (cookieMap.containsKey(name)) {
return cookieMap.get(name);
}else {
return null;
}
}
/**
* 将cookie封装成Map
* @param request
* @return
*/
private static Map<String, Cookie> readCookieMap(HttpServletRequest request) {
Map<String, Cookie> cookieMap = new HashMap<>();
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie: cookies) {
cookieMap.put(cookie.getName(), cookie);
}
}
return cookieMap;
}
}
3、配置文件
spring:
redis:
host: 192.168.116.140
port: 6379
4、结果
访问:http://t238997p11.qicp.vip/sell/seller/login 后:cookie和redis都有内容了
访问:http://t238997p11.qicp.vip/sell/seller/logout 后:cookie和redis中的内容又都被删除了
以上就是登录登出的逻辑及代码,欢迎指教!!!