好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

微信小程序登录状态java后台解密

一、 登录 流程图

二、 微信小程序 端

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

dologin:function(callback = () =>{}){

let that = this ;

wx.login({

  success:function(loginres){

   if (loginres){

    //获取用户信息

    wx.getuserinfo({

     withcredentials: true , //非必填 默认为true

     success:function(infores){

      console.log(infores, '>>>' );

      //请求服务端的登录接口

      wx.request({

       url: api.loginurl,

       data:{

        code:loginres.code, //临时登录凭证

        rawdata:infores.rawdata, //用户非敏感信息

        signature:infores.signature, //签名

        encryptedata:infores.encrypteddata, //用户敏感信息

        iv:infores.iv //解密算法的向量

       },

       success:function(res){

        console.log( 'login success' );

        res = res.data;

        if (res.result== 0 ){

         that.globaldata.userinfo = res.userinfo;

         wx.setstoragesync( 'userinfo' ,json.stringify(res.userinfo));

         wx.setstoragesync( 'loginflag' ,res.skey);

         console.log( "skey=" +res.skey);

         callback();

        } else {

         that.showinfo( 'res.errmsg' );

        }

       },

       fail:function(error){

        //调用服务端登录接口失败

        // that.showinfo('调用接口失败');

        console.log(error);

       }

      });

     }

    });

   } else {

 

   }

  }

});

}

微信小程序端发起登录请求,携带的参数主要有:

?

1

2

3

4

5

code:loginres.code, //临时登录凭证

rawdata:infores.rawdata, //用户非敏感信息

signature:infores.signature, //签名

encryptedata:infores.encrypteddata, //用户敏感信息

iv:infores.iv //解密算法的向量

需要的数据主要有:

result、userinfo和skey

result用来判断是否登录成功,userinfo是用户的一些信息,保存在缓存中,不用每次都从后台获取,skey是用户登录态标识,也放在缓存中,如果skey存在就直接登录,维护用户的登录状态,具有时效性

三、java后台

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

@responsebody

@requestmapping ( "/login" )

public map<string,object> dologin(model model,

                  @requestparam (value = "code" ,required = false ) string code,

                  @requestparam (value = "rawdata" ,required = false ) string rawdata,

                  @requestparam (value = "signature" ,required = false ) string signature,

                  @requestparam (value = "encryptedata" ,required = false ) string encryptedata,

                  @requestparam (value = "iv" ,required = false ) string iv){

   log.info( "start get sessionkey" );

 

 

   map<string,object> map = new hashmap<string, object>( );

   system.out.println( "用户非敏感信息" +rawdata);

 

   jsonobject rawdatajson = json.parseobject( rawdata );

 

   system.out.println( "签名" +signature);

   jsonobject sessionkeyopenid = getsessionkeyoropenid( code );

   system.out.println( "post请求获取的sessionandopenid=" +sessionkeyopenid);

 

   string openid = sessionkeyopenid.getstring( "openid" );

 

   string sessionkey = sessionkeyopenid.getstring( "session_key" );

 

   system.out.println( "openid=" +openid+ ",session_key=" +sessionkey);

 

   user user = userservice.findbyopenid( openid );

   //uuid生成唯一key

   string skey = uuid.randomuuid().tostring();

   if (user== null ){

     //入库

     string nickname = rawdatajson.getstring( "nickname" );

     string avatarurl = rawdatajson.getstring( "avatarurl" );

     string gender = rawdatajson.getstring( "gender" );

     string city = rawdatajson.getstring( "city" );

     string country = rawdatajson.getstring( "country" );

     string province = rawdatajson.getstring( "province" );

 

 

     user = new user();

     user.setuid( openid );

     user.setcreatetime( new date( ) );

     user.setsessionkey( sessionkey );

     user.setubalance( 0 );

     user.setskey( skey );

     user.setuaddress( country+ " " +province+ " " +city );

     user.setuavatar( avatarurl );

     user.setugender( integer.parseint( gender ) );

     user.setuname( nickname );

     user.setupdatetime( new date( ) );

 

     userservice.insert( user );

   } else {

     //已存在

     log.info( "用户openid已存在,不需要插入" );

   }

   //根据openid查询skey是否存在

   string skey_redis = (string) redistemplate.opsforvalue().get( openid );

   if (stringutils.isnotblank( skey_redis )){

     //存在 删除 skey 重新生成skey 将skey返回

     redistemplate.delete( skey_redis );

 

   }

     // 缓存一份新的

     jsonobject sessionobj = new jsonobject( );

     sessionobj.put( "openid" ,openid );

     sessionobj.put( "sessionkey" ,sessionkey );

     redistemplate.opsforvalue().set( skey,sessionobj.tojsonstring() );

     redistemplate.opsforvalue().set( openid,skey );

 

     //把新的sessionkey和oppenid返回给小程序

     map.put( "skey" ,skey );

 

 

 

   map.put( "result" , "0" );

 

 

 

   jsonobject userinfo = getuserinfo( encryptedata, sessionkey, iv );

   system.out.println( "根据解密算法获取的userinfo=" +userinfo);

   userinfo.put( "balance" ,user.getubalance() );

   map.put( "userinfo" ,userinfo );

 

   return map;

}

获取openid和sessionkey方法

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

public static jsonobject getsessionkeyoropenid(string code){

   //微信端登录code

   string wxcode = code;

   string requesturl = "https://api.weixin.qq测试数据/sns/jscode2session" ;

   map<string,string> requesturlparam = new hashmap<string, string>( );

   requesturlparam.put( "appid" , "你的小程序appid" ); //小程序appid

   requesturlparam.put( "secret" , "你的小程序appsecret" );

   requesturlparam.put( "js_code" ,wxcode ); //小程序端返回的code

   requesturlparam.put( "grant_type" , "authorization_code" ); //默认参数

 

   //发送post请求读取调用微信接口获取openid用户唯一标识

   jsonobject jsonobject = json.parseobject( urlutil.sendpost( requesturl,requesturlparam ));

   return jsonobject;

}

解密用户敏感数据获取用户信息

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

public static jsonobject getuserinfo(string encrypteddata,string sessionkey,string iv){

   // 被加密的数据

   byte [] databyte = base64.decode(encrypteddata);

   // 加密秘钥

   byte [] keybyte = base64.decode(sessionkey);

   // 偏移量

   byte [] ivbyte = base64.decode(iv);

   try {

     // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要

     int base = 16 ;

     if (keybyte.length % base != 0 ) {

       int groups = keybyte.length / base + (keybyte.length % base != 0 ? 1 : 0 );

       byte [] temp = new byte [groups * base];

       arrays.fill(temp, ( byte ) 0 );

       system.arraycopy(keybyte, 0 , temp, 0 , keybyte.length);

       keybyte = temp;

     }

     // 初始化

     security.addprovider( new bouncycastleprovider());

     cipher cipher = cipher.getinstance( "aes/cbc/pkcs7padding" , "bc" );

     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, "utf-8" );

       return json.parseobject(result);

     }

   } catch (nosuchalgorithmexception e) {

     log.error(e.getmessage(), e);

   } catch (nosuchpaddingexception e) {

     log.error(e.getmessage(), e);

   } catch (invalidparameterspecexception e) {

     log.error(e.getmessage(), e);

   } catch (illegalblocksizeexception e) {

     log.error(e.getmessage(), e);

   } catch (badpaddingexception e) {

     log.error(e.getmessage(), e);

   } catch (unsupportedencodingexception e) {

     log.error(e.getmessage(), e);

   } catch (invalidkeyexception e) {

     log.error(e.getmessage(), e);

   } catch (invalidalgorithmparameterexception e) {

     log.error(e.getmessage(), e);

   } catch (nosuchproviderexception e) {

     log.error(e.getmessage(), e);

   }

   return null ;

}

四、流程

1.小程序端发起请求并携带主要参数

2.java后台接到/login请求后,根据code去调用微信接口获取用户唯一标识openid和sessionkey

3.根据openid查询mysql数据库,判断该用户是否存在,如果不存在将用户非敏感信息和其他初始化数据存入到数据库中,如果已存在,不操作

4.根据openid查询redis数据库,判断openid对应的skey是否存在,如果存在则删除原来老的skey以及对应的openid和sessionkey

5.通过uuid生成唯一的skey,用openid做键,skey做值,存入到redis中

6.然后把skey做键,openid和sessionkey的json串做值也重新存入到redis中

7.根据解密算法,参数有encrypteddata、sessionkey和iv,获取用户信息userinfo,如果userinfo字段不满足需要,可通过userinfo.put( [balance],user.getubalance() );添加所需要的字段和值

8.将微信小程序需要的数据封装到map中,返回给小程序端

?

1

2

3

4

map.put( "skey" ,skey );

map.put( "result" , "0" );

map.put( "userinfo" ,userinfo );

return map;

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

原文链接:https://blog.csdn.net/qq_38977097/article/details/80778105

查看更多关于微信小程序登录状态java后台解密的详细内容...

  阅读:23次