微信授权登陆-app

app接入第三方微信登陆功能:

移动应用微信登录是基于OAuth2.0协议标准 构建的微信OAuth2.0授权登录系统,前提你需要到微信开放平台注册开发者帐号,并拥有一个已审核通过的移动应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程。

接入微信登陆授权步骤:

1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;

2. 通过code参数加上AppID和AppSecret等,通过API换取access_token;

3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。

注意:同一个微信开放平台下绑定的用户,在不同的应用下用户的UnionID就是相同的,openId是不相同的。

获取access_token流程:

微信授权登陆-app_第1张图片

第一步:请求CODE:

需要app调起微信


第二步:通过code获取access_token:

请求路径:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

参数:

appid 应用唯一标识,在微信开放平台提交应用审核通过后获得
secret 应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
code 填写第一步获取的code参数
grant_type 填authorization_code

 appid与secret需要通过注册获取。

第三步:通过access_token调用接口

获取access_token后,进行接口调用,有以下前提:

  • access_token有效且未超时;
  • 微信用户已授权给第三方应用帐号相应接口作用域(scope)。

代码:

请求微信工具类:

package com.maobc.util;

import com.alibaba.fastjson.JSONObject;
import com.maobc.entity.jar.Member;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.poi.ss.formula.functions.T;
import springfox.documentation.spring.web.json.Json;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;

/**
 * @program: maobc-small_routine
 * @description: app用户登陆
 * @author: z.hw
 **/
public class WeixinLoginUtils {
    /**
     * 微信登陆通过code获取accessToken
     * @param appId
     * @param userAppSecret
     * @param code
     * @return
     * @throws Exception
     */
    public StringBuilder getAccessTokenBycode(String appId,String userAppSecret,String code) throws Exception{
        //查看官方文档 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317853&token=&lang=
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+appId+"&secret="+
                userAppSecret+"&code="+code+"&grant_type=authorization_code";
        URI uri = URI.create(url);
        HttpClient client = HttpClients.createDefault();
        HttpGet get = new HttpGet(uri);
        HttpResponse response=client.execute(get);
        StringBuilder sb = new StringBuilder();
        if (response.getStatusLine().getStatusCode() == 200) {
            HttpEntity entity = response.getEntity();
            BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
            for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
                sb.append(temp);
            }
        }
        return sb;
    }


    /**
     * access_token是否有效的验证
     * @param accessToken
     * @param openID
     * @return
     */
    public boolean isAccessTokenIsInvalid(String accessToken,String openID) throws Exception{
        String url = "https://api.weixin.qq.com/sns/auth?access_token=" + accessToken + "&openid=" + openID;
        URI uri = URI.create(url);
        HttpClient client = HttpClients.createDefault();
        HttpGet get = new HttpGet(uri);
        HttpResponse response = client.execute(get);
        if (response.getStatusLine().getStatusCode() == 200) {
            HttpEntity entity = response.getEntity();

            BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
            StringBuilder sb = new StringBuilder();

            for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
                sb.append(temp);
            }
            JSONObject object = JSONObject.parseObject(sb.toString().trim());
            int errcode = object.getInteger("errcode");
            if (errcode == 0) {
                //未失效
                return true;
            }
        }
        return false;
    }

    /**
     * access_token       接口调用凭证
     * expires_in        access_token接口调用凭证超时时间,单位(秒)
     * refresh_token     用户刷新access_token
     * openid           授权用户唯一标识
     * scope          用户授权的作用域,使用逗号(,)分隔
     * @param APP_ID
     */
    public JSONObject refreshAccessToken(String APP_ID,String refreshToken) throws Exception{
        /**
         * access_token是调用授权关系接口的调用凭证,由于access_token有效期(目前为2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新,access_token刷新结果有两种:
         *
         * 1.若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间;
         *
         * 2.若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token。
         *
         * refresh_token拥有较长的有效期(30天)且无法续期,当refresh_token失效的后,需要用户重新授权后才可以继续获取用户头像昵称。
         */
        String uri = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + APP_ID + "&grant_type=refresh_token&refresh_token=" + refreshToken;
        HttpClient client = HttpClients.createDefault();
        HttpGet get = new HttpGet(URI.create(uri));
        HttpResponse response = client.execute(get);
        JSONObject object =new JSONObject();
        if (response.getStatusLine().getStatusCode() == 200) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
            StringBuilder builder = new StringBuilder();
            for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
                builder.append(temp);
            }
            object = JSONObject.parseObject(builder.toString().trim());
        }
        return object;
    }

    /**
     * 得到用户基本信息
     * @param accessToken
     * @param openId
     * @param tClass
     * @return
     * @throws Exception
     */
    public  T    getAppWeiXinUserInfo(String accessToken, String openId, Class tClass) throws Exception{
        String uri = "https://api.weixin.qq.com/sns/userinfo?access_token="+accessToken+"&openid="+openId;
        HttpClient client = HttpClients.createDefault();
        HttpGet get = new HttpGet(URI.create(uri));
        HttpResponse response = client.execute(get);

        if (response.getStatusLine().getStatusCode() == 200) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
            StringBuilder builder = new StringBuilder();
            for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
                System.out.println(temp);
                builder.append(temp);
            }
            return JSONObject.parseObject(builder.toString(), tClass);
        }
        return null;
    }

}

controller: 

   /**
     * @Description:  app微信登陆
     * @Author: z.hw
     */
    @RequestMapping(value = {"getUserInfoByAppCode"})
    @ApiOperation(value = "getUserInfoByAppCode", notes = "不分页", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiResponses(value = {
            @ApiResponse(code = 404, message = "Not Found"),
            @ApiResponse(code = 400, message = "No Name Provided"),
    })
    publicApiResult getUserInfoByApp(@Validated UserAppAuthority userAppAuthority){
        return memberService.getUserInfoByApp(userAppAuthority);
    }

请求体:

/**
 * @program: maobc-small_routine
 * @description: app微信授权
 * @author: z.hw
 **/
@Data
public class UserAppAuthority {

    //新旧app 用来备份 自定义数据
    @NotNull(message = "类型不能为空")
    @NotEmpty(message = "类型不能为空")
    private String type;

    //重点需要 app调起微信获取到的code
    @NotEmpty(message = "code不能为空")
    @NotNull(message = "code不能为空")
    private String code;

}
ApiResult:
@Data
@ToString(callSuper = true)
@EqualsAndHashCode
public class ApiResult implements Serializable {

    /**
     * 状态码
     * 0表示成功
     */
    private String  code = "0000";

    /**
     * 状态信息
     */
    private String msg = "调用成功";

    private Object result;
   
    。。。。。。。。。。。。。

}

 业务层:

/**
     * @Description: 用户app微信登陆
     * @Param:
     * @return:
     * @Author: z.hw
     */
    public ApiResult getUserInfoByApp(UserAppAuthority userAppAuthority) {
        try {
            Member member = new Member();
            BeanUtils.copyProperties(userAppAuthority, member);

            //调用微信授权
            WeixinLoginUtils weixinLoginUtils = new WeixinLoginUtils();
            StringBuilder stringBuilder = weixinLoginUtils.getAccessTokenBycode(commConfig.userAppID, commConfig.userAppSecret, userAppAuthority.getCode());
            if (stringBuilder != null) {
                if (stringBuilder.toString().trim().contains("errcode")) {
                    return ApiResult.Fail();
                }
                JSONObject object = JSONObject.parseObject(stringBuilder.toString().trim());
                String accessToken = object.getString("access_token"); //接口调用凭证
                String openID = object.getString("openid"); //授权用户唯一标识
                //获取微信用户基本信息
                WeiXinParam appWeiXinUserInfo = weixinLoginUtils.getAppWeiXinUserInfo(accessToken, openID, WeiXinParam.class);
                // TODO 业务逻辑
                 。。。。。。。。。。。。
                return ApiResult.build(member);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return MaobcApiResult.Fail();
    }
Member:

  


import lombok.*;

import javax.persistence.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

/**
 * @author
 */
@Entity
@Table(name = "cat_member")
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Member implements Serializable {
    private static final long serialVersionUID = -27353316177184L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private String id;

    /**
     * 账号状态:0 正常;1 冻结
     */
    @Column(name = "status")
    private String status;

    /**
     * del_flag
     */
    @Column(name = "del_flag")
    private String delFlag;

    /**
     * 手机
     */
    @Column(name = "mobile_phone")
    private String mobilePhone;

    /**
     * 用户名
     */
    @Column(name = "user_name")
    private String userName;

    /**
     * 邮箱
     */
    @Column(name = "email")
    private String email;

    /**
     * 用户密码
     */
    @Column(name = "password")
    private String password;

    /**
     * 昵称
     */
    @Column(name = "nickname")
    private String nickname;

    /**
     * 性别
     */
    @Column(name = "sex")
    private String sex;

    /**
     * 头像url
     */
    @Column(name = "headimgurl")
    private String headimgurl;

    /**
     * 城市
     */
    @Column(name = "city")
    private String city;

    /**
     * 国家
     */
    @Column(name = "country")
    private String country;

    /**
     * 省份
     */
    @Column(name = "province")
    private String province;

    /**
     * 语言
     */
    @Column(name = "language")
    private String language;

    /**
     * 备注
     */
    @Column(name = "remark")
    private String remark;

    /**
     * 生日
     */
    @Column(name = "birthday")
    private String birthday;

    /**
     * 地址
     */
    @Column(name = "address")
    private String address;

    /**
     * 会员积分
     */
    @Column(name = "accumulate_points")
    private BigDecimal accumulatePoints;

    /**
     * 平台会员等级
     */
    @Column(name = "level")
    private Integer level;

    /**
     * cat_membership会员类型表的ID
     */
    @Column(name = "membership_id")
    private String membershipId;

    /**
     * 创建人
     */
    @Column(name = "create_by")
    private String createBy;

    /**
     * 创建时间
     */
    @Column(name = "create_date")
    private Date createDate;

    /**
     * 修改人
     */
    @Column(name = "update_by")
    private String updateBy;

    /**
     * 修改时间
     */
    @Column(name = "update_date")
    private Date updateDate;

    /**
     * 会员是否同意条款标识(0-未同意 1-同意)
     */
    @Column(name = "item_status")
    private Integer itemStatus;

    private String openid;

    private String unionId;

    private String type;

    //是否绑定手机号码
    private String isBindedPhone;

    private String oauthId;

    private String memberId;

    private String outhId;


}

WeiXinParam : 


import lombok.Data;

@Data
public class WeiXinParam {
    String openid = "";
    String unionId = "";
    String sex = "1";
    String nickname = "";
    String city = "";
    String province = "";
    String country = "";
    String avatarUrl = "";
    String headimgurl="";

}

参考资料:

微信开发平台:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&lang=zh_CN 

 

你可能感兴趣的:(java)