欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Springboot网站第三方登录 微信登录

程序员文章站 2024-02-22 12:28:34
微信开放平台接入,官网:,在官网注册并添加应用后即可获得app_id和app_secret。 步骤一:创建一个继承authservice的接口,wechatauthser...

微信开放平台接入,官网:,在官网注册并添加应用后即可获得app_id和app_secret。

步骤一:创建一个继承authservice的接口,wechatauthservice,如下

public interface wechatauthservice extends authservice {
  public jsonobject getuserinfo(string accesstoken, string openid);
}

步骤二:wechatservice的具体实现如下

@service
public class wechatauthserviceimpl extends defaultauthserviceimpl implements wechatauthservice {

  private logger logger = loggerfactory.getlogger(wechatauthserviceimpl.class);

//请求此地址即跳转到二维码登录界面
  private static final string authorization_url =
      "https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect";

  // 获取用户 openid 和access——toke 的 url
  private static final string accesstoke_openid_url =
      "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";

  private static final string refresh_token_url =
      "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s";

  private static final string user_info_url =
      "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_cn";

  private static final string app_id="xxxxxx";
  private static final string app_secret="xxxxxx";
  private static final string scope = "snsapi_login";

  private string callbackurl = "https://www.xxx.cn/auth/wechat"; //回调域名

  @override
  public string getauthorizationurl() throws unsupportedencodingexception {
    callbackurl = urlencoder.encode(callbackurl,"utf-8");
    string url = string.format(authorization_url,app_id,callbackurl,scope,system.currenttimemillis());
    return url;
  }


  @override
  public string getaccesstoken(string code) {
    string url = string.format(accesstoke_openid_url,app_id,app_secret,code);

    uricomponentsbuilder builder = uricomponentsbuilder.fromhttpurl(url);
    uri uri = builder.build().encode().touri();

    string resp = getresttemplate().getforobject(uri, string.class);
    logger.error("getaccesstoken resp = "+resp);
    if(resp.contains("openid")){
      jsonobject jsonobject = jsonobject.parseobject(resp);
      string access_token = jsonobject.getstring("access_token");
      string openid = jsonobject.getstring("openid");;

      jsonobject res = new jsonobject();
      res.put("access_token",access_token);
      res.put("openid",openid);
      res.put("refresh_token",jsonobject.getstring("refresh_token"));

      return res.tojsonstring();
    }else{
      throw new serviceexception("获取token失败,msg = "+resp);
    }
  }

  //微信接口中,token和openid是一起返回,故此方法不需实现
  @override
  public string getopenid(string accesstoken) {
    return null;
  }

  @override
  public jsonobject getuserinfo(string accesstoken, string openid){
    string url = string.format(user_info_url, accesstoken, openid);
    uricomponentsbuilder builder = uricomponentsbuilder.fromhttpurl(url);
    uri uri = builder.build().encode().touri();

    string resp = getresttemplate().getforobject(uri, string.class);
    logger.error("getuserinfo resp = "+resp);
    if(resp.contains("errcode")){
      throw new serviceexception("获取用户信息错误,msg = "+resp);
    }else{
      jsonobject data =jsonobject.parseobject(resp);

      jsonobject result = new jsonobject();
      result.put("id",data.getstring("unionid"));
      result.put("nickname",data.getstring("nickname"));
      result.put("avatar",data.getstring("headimgurl"));

      return result;
    }
  }

  //微信的token只有2小时的有效期,过时需要重新获取,所以官方提供了
  //根据refresh_token 刷新获取token的方法,本项目仅仅是获取用户
  //信息,并将信息存入库,所以两个小时也已经足够了
  @override
  public string refreshtoken(string refresh_token) {

    string url = string.format(refresh_token_url,app_id,refresh_token);

    uricomponentsbuilder builder = uricomponentsbuilder.fromhttpurl(url);
    uri uri = builder.build().encode().touri();

    responseentity<jsonobject> resp = getresttemplate().getforentity(uri,jsonobject.class);
    jsonobject jsonobject = resp.getbody();

    string access_token = jsonobject.getstring("access_token");
    return access_token;
  }
}

步骤三:

在controller中调用,代码如下:

@requestmapping(value = "/wxloginpage",method = requestmethod.get)
  public jsonobject wxloginpage() throws exception {
    string uri = wechatauthservice.getauthorizationurl();
    return loginpage(uri);
  }

  @requestmapping(value = "/wechat")
  public void callback(string code,httpservletrequest request,httpservletresponse response) throws exception {
    string result = wechatauthservice.getaccesstoken(code);
    jsonobject jsonobject = jsonobject.parseobject(result);

    string access_token = jsonobject.getstring("access_token");
    string openid = jsonobject.getstring("openid");
//    string refresh_token = jsonobject.getstring("refresh_token");

    // 保存 access_token 到 cookie,两小时过期
    cookie accesstokencookie = new cookie("accesstoken", access_token);
    accesstokencookie.setmaxage(60 *2);
    response.addcookie(accesstokencookie);

    cookie openidcookie = new cookie("openid", openid);
    openidcookie.setmaxage(60 *2);
    response.addcookie(openidcookie);

    //根据openid判断用户是否已经登陆过
    kmsuser user = userservice.getuserbycondition(openid);

    if (user == null) {
      response.sendredirect(request.getcontextpath() + "/student/html/index.min.html#/bind?type="+constants.login_type_wechat);
    } else {
      //如果用户已存在,则直接登录
      response.sendredirect(request.getcontextpath() + "/student/html/index.min.html#/app/home?open_id=" + openid);
    }
  }

步骤四:

前台js中,先请求auth/wxloginpage,获取授权地址,等用户授权后会回调/auth/wechat,在此方法中进行逻辑处理即可。

遇到过的坑:

1.在微信官网中配置回调域名的时候,不需要些http或https协议,只需要写上域即可,例如http://baidu.com,只需要填写baidu.com即可,如果是想要跳转到项目下面的某个controller的某个方法中,如baidu.com/auth/wechat ,配置的时候也只需要配baidu.com,不需要指定后面的auth/wechat,后面的地址在代码中配置回调的地址的时候写上即可,代码中应该配置为https://baidu.com/auth/wechat
2.在跳转到授权二维码界面的时候,会遇到有的时候二维码出不来的状况,这是因为代码中的回调地址的问题,按照上面代码中的方式配置应该是没有问题的

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。