微信小程序授权登录获取用户信息详解

微信小程序授权登录获取用户信息详解今天来说一下微信小程序的授权登录获取用户信息,首先我们看微信提供的小程序开发文档:https://blog.csdn.net/qq_41971087/article/details/82466647微信登录的流程和步骤:步骤:(个人):第一步:微信小程序调用login和getUserInfo(),拿到code和encryptedData,iv,传入到后台进行业务处理第二步:……

大家好,欢迎来到IT知识分享网。

今天来说一下微信小程序的授权登录获取用户信息,首先我们看微信提供的小程序开发文档:
https://blog.csdn.net/qq_41971087/article/details/82466647
微信登录的流程和步骤:
这里写图片描述
步骤:(个人):
第一步:微信小程序调用login和getUserInfo(),拿到code和encryptedData,iv,传入到后台进行业务处理
第二步:拿到code调用登录凭证校验接口去获取用户,openid和session_key
第三步:获取到session_key和encryptedData,iv去进行AES解密,解密成功后就可以拿到用户信息

页面中的代码:

<view class="userinfo">
   <button wx:if="{
  
  {!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo" 
   style="border:0px solid red;background-color:#fff;width:330rpx;" plain='true'>
     <image src="/images/user.png"  style="width:200rpx;height:200rpx;"/> 
     <view>请点击头像登录</view>
     </button>
     </view>

js:

 getUserInfo: function (e) {
    console.log(5);
    console.log(e)
    if (e.detail.userInfo) {
      app.globalData.userInfo = e.detail.userInfo
      this.setData({
        userInfo: e.detail.userInfo,
        hasUserInfo: true
      })
    } else {
      this.openSetting();
    }

  },
  login: function () {
    console.log(111)
    var that = this
    var thist = this;
    // if (typeof success == "function") {
    //   console.log(6);
    //   console.log('success');
    //   this.data.getUserInfoSuccess = success
    // }
    wx.login({
      success: function (res) {
        var code = res.code;
        console.log(code);
        wx.getUserInfo({
          success: function (res) {
            console.log(res);
            wx.request({
              url: app.server.hostUrl + '/api/auth/login_by_weixin.do',//自己的服务接口地址,这里是去拿到code去后台进行业务处理,调用微信接口拿到用户openid和凭证,在解密拿到用户数据
              method: 'post',
              header: {
                'content-type': 'application/x-www-form-urlencoded'
              },
              data: { encryptedData: res.encryptedData, iv: res.iv, code: code },
              success: function (data) {
                wx.setStorage({
                  key: "userif",
                  data: data.data.userinfo
                })
                console.info(data);
                //4.解密成功后 获取自己服务器返回的结果
                if (data.data.code == 1) {
                  var userInfo_ = data.data.userinfo;
                  console.log(7);
                  app.globalData.userInfo = userInfo_
                  that.setData({
                    getUserInfoFail: false,
                    userInf: userInfo_,
                    hasUserInfo: true

                  })
                  thist.setData({
                    datas: userInfo_,
                    index: 1
                  })
                  console.log(userInfo_)
                  that.onLoad();
                } else {
                  console.log('解密失败')
                }

              },
              fail: function () {
                console.log('系统错误')
              }
            })

            //平台登录
          },
          fail: function (res) {
            console.log(8);
            console.log(res);
            that.setData({
              getUserInfoFail: true
            })
          }
        })
      }
    })
  },
  //跳转设置页面授权
  openSetting: function () {
    var that = this
    if (wx.openSetting) {
      wx.openSetting({
        success: function (res) {
          console.log(9);
          //尝试再次登录
          that.login()
        }
      })
    } else {
      console.log(10);
      wx.showModal({
        title: '授权提示',
        content: '小程序需要您的微信授权才能使用哦~ 错过授权页面的处理方法:删除小程序->重新搜索进入->点击授权按钮'
      })
    }
  }

JAVA后台代码Controller层:

 /**
     *微信登录
     * @param code 凭证
     * @param encryptedData 用户数据
     * @param iv 用户数据
     * @param request request作用域:
     * @return map
     */
    @RequestMapping("/login_by_weixin")
    @ResponseBody
    public Map loginByWeixin(String code, String encryptedData, String iv, HttpServletRequest request)
    {
        	Map<String,Object> map  =new HashMap<String, Object>();
			
        	String sendGet=userService.loginByWeixin(code); //根据code去调用接口获取用户openid和session_key
			
            JSONObject json = JSONObject.fromObject(sendGet);
            System.out.println("返回过来的json数据:"+json.toString());
            String sessionkey=json.get("session_key").toString(); //会话秘钥
            String openid=json.get("openid").toString(); //用户唯一标识
            try{
			//拿到用户session_key和用户敏感数据进行解密,拿到用户信息。
             String decrypts=AesCbcUtil.decrypt(encryptedData,sessionkey,iv,"utf-8");//解密
               JSONObject jsons = JSONObject.fromObject(decrypts);
                   String nickName=jsons.get("nickName").toString(); //用户昵称
                   String jsonsds=jsonsd.get("avatarUrl").toString(); //用户头像
					jsons.get("avatarUrl").toString(); //头像
					jsons.get("gender").toString();//性别 
                   jsons.get("unionid").toString(); //unionid
                   jsons.get("city").toString(); //城市
                  jsons.get("province").toString();//省份
                   jsons.get("country").toString(); //国家
            }catch (Exception e) {
             e.printStackTrace();
            }
    }

这里拿到用户信息自己去做处理,保存到数据库中,这里我就不编写了
userServiceImpl.java:

 /**
     *微信登录业务实现类:
     * @param openid 用户id
     * @return User
     */
	 @Override
    public String loginByWeixin(String code, String encryptedData, String iv) {
        Map<String, Object> map = new HashMap<String, Object>();
		//发送	https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code 获取用户的openid和session_key
		//注意这个是 WeChatTool.wxspAppid 是微信小程序的appid 从微信小程序后台获取 WeChatTool.wxspSecret 这个也一样,我这里是用了常量来进行保存方便多次使用
        String params = "appid=" + WeChatTool.wxspAppid + "&secret=" + WeChatTool.wxspSecret + "&js_code=" + code + "&grant_type=authorization_code";
        String sendGet = Httprequests.sendGet(WeChatTool.url, params); //发起请求拿到key和openid
        return sendGet;
    }

Httprequests.java(发送网络请求的工具类)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.servlet.http.HttpServletRequest;
/**
 * <p>User: xxx
 * <p>Date: 14-1-28
 * <p>Version: 1.0
 * 描述: http发起请求:
 */
public class Httprequests {


	//测试,发送请求是否成功:
    public static void main(String[] aegs) {
        String string = Httprequests.sendGet("http://v.qq.com/x/cover/kvehb7okfxqstmc.html?vid=e01957zem6o","");
        System.out.print(string);
    }

	//发送GET请求:
    public static String  sendGet (String url,String param) {
        String result ="";
        BufferedReader in  =null;
        try {
            String urlNameString = url +"?" +param;
            System.out.println("发送的链接请求:"+urlNameString);
            URL reaurl = new URL(urlNameString);

            URLConnection connection  = reaurl.openConnection();

            //设置通用
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

            //建立实际的连接
            connection.connect();

            Map<String, List<String>> map = connection.getHeaderFields();
            //定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }


    /**
     * 向指定 URL 发送POST方法的请求
     * @param url 发送请求的 URL
     * @param param 参数
     * @return String 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常!"+e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(IOException ex){
                ex.printStackTrace();
            }
        }
        return result;
    }

}

AesCbcUtil.java(拿用户的session_key和微信小程序传过来的iv和encryptedData进行解密的工具类)

import java.io.UnsupportedEncodingException;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidParameterSpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.management.openmbean.InvalidKeyException;
import org.apache.commons.codec.binary.Base64;
/**
 * <p>User: qrn
 * <p>Date: 14-1-28
 * <p>Version: 1.0
 * 描述: 解密
 */
public class AesCbcUtil {



    /**
     * AES解密
     *
     * @param encryptedData  包括敏感数据在内的完整用户信息的加密数据,
     * @param key    秘钥
     * @param iv     加密算法的初始向量,
     * @param encodingFormat 解密后的结果需要进行的编码
     * @return String
     * @see  Exception
     */
    public static String decrypt(String encryptedData,String key, String iv, String encodingFormat) throws Exception {
//        initialize();

        //被加密的数据
        byte[] dataByte = Base64.decodeBase64(data);
        //加密秘钥
        byte[] keyByte = Base64.decodeBase64(key);
        //偏移量
        byte[] ivByte = Base64.decodeBase64(iv);


        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");

            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, encodingFormat);
                return result;
            }
            return null;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidParameterSpecException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

}

如果上面的执行没有错误的话,就可以拿到用户的信息,这个代码应该是不会出问题,如果有问题请下发评论我会及时的回答,其实微信的开发文档中这些东西以经写的很清楚,希望微信开发的朋友可以认真仔细的观看微信文档,希望这篇文字对大家有用,谢谢

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/24058.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信