1. 程式人生 > >JAVA實現微信網頁授權的實列程式碼

JAVA實現微信網頁授權的實列程式碼

1、需要有一個公眾號(我這裡用的測試號),拿到AppID和AppSecret;

2、進入公眾號開發者中心頁配置授權回撥域名。具體位置:介面許可權-網頁服務-網頁賬號-網頁授權獲取使用者基本資訊-修改

注意,這裡僅需填寫全域名(如www.qq.com、www.baidu.com),勿加 http:// 等協議頭及具體的地址欄位;

 我們可以通過使用Ngrok來虛擬一個域名對映到本地開發環境,網址https://www.ngrok.cc/,大家自己去下載學習怎麼使用

同時還需要掃一下這個二維碼

授權步驟:

1、引導使用者進入授權頁面同意授權,獲取code

2、通過code換取網頁授權access_token(與基礎支援中的access_token不同)

3、通過網頁授權access_token和openid獲取使用者基本資訊

先看一下我的專案結構:

web.xml相關程式碼:

?

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

<?xml version="1.0" encoding="UTF-8"?>

<display-name>WxAuth</display-name>

<welcome-file-list>

<welcome-file>index.html</welcome-file>

<welcome-file>index.htm</welcome-file>

<

welcome-file>index.jsp</welcome-file>

<welcome-file>default.html</welcome-file>

<welcome-file>default.htm</welcome-file>

<welcome-file>default.jsp</welcome-file>

</welcome-file-list>

<servlet>

<servlet-name>wxCallBack</servlet-name>

<servlet-class>com.xingshang.servlet.CallBackSerclet</servlet-class>

<init-param>

<param-name>dbUrl</param-name>

</init-param>

<init-param>

<param-name>driverClassName</param-name>

<param-value>com.mysql.jdbc.Driver</param-value>

</init-param>

<init-param>

<param-name>userName</param-name>

<param-value>root</param-value>

</init-param>

<init-param>

<param-name>passWord</param-name>

<param-value>123456</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>wxCallBack</servlet-name>

<url-pattern>/wxCallBack</url-pattern>

</servlet-mapping>

</web-app>

AuthUtil工具類:

?

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

package com.xingshang.util;

import java.io.IOException;

import org.apache.http.HttpEntity;

import org.apache.http.HttpResponse;

import org.apache.http.client.ClientProtocolException;

import org.apache.http.client.methods.HttpGet;

import org.apache.http.impl.client.DefaultHttpClient;

import org.apache.http.util.EntityUtils;

import net.sf.json.JSONObject;

public class AuthUtil {

public static final String APPID = "wx45c1428e5584fcdb";

public static final String APPSECRET = "98174450eb706ada330f37e646be85d5";

public static JSONObject doGetJson(String url) throws ClientProtocolException, IOException{

JSONObject jsonObject = null;

//首先初始化HttpClient物件

DefaultHttpClient client = new DefaultHttpClient();

//通過get方式進行提交

HttpGet httpGet = new HttpGet(url);

//通過HTTPclient的execute方法進行傳送請求

HttpResponse response = client.execute(httpGet);

//從response裡面拿自己想要的結果

HttpEntity entity = response.getEntity();

if(entity != null){

String result = EntityUtils.toString(entity,"UTF-8");

jsonObject = jsonObject.fromObject(result);

}

//把連結釋放掉

httpGet.releaseConnection();

return jsonObject;

}

}

Java實現:

1、引導使用者進入授權頁面同意授權,獲取code

這一步其實就是將需要授權的頁面url拼接到微信的認證請求接口裡面,比如需要使用者在訪問頁面 時進行授權認證

其中的scope引數有兩個值:

snsapi_base:只能獲取到使用者openid。好處是靜預設證,無需使用者手動點選認證按鈕,感覺上像是直接進入網站一樣。

snsapi_userinfo:可以獲取到openid、暱稱、頭像、所在地等資訊。需要使用者手動點選認證按鈕。

相關程式碼

?

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

package com.xingshang.servlet;

import java.io.IOException;

import java.net.URLEncoder;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.xingshang.util.AuthUtil;

/**

* 入口地址

* @author Administrator

*

*/

@WebServlet("/wxLogin")

public class LoginServlet extends HttpServlet {

/**

*

*/

private static final long serialVersionUID = 1L;

@Override

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//第一步:引導使用者進入授權頁面同意授權,獲取code

//回撥地址

//授權頁面地址

+ "&redirect_uri="+URLEncoder.encode(backUrl)

+ "&response_type=code"

+ "&scope=snsapi_userinfo"

+ "&state=STATE#wechat_redirect";

//重定向到授權頁面

response.sendRedirect(url);

}

}

2、通過第一步獲取的code換取網頁授權access_token(與基礎支援中的access_token不同)

這一步需要在控制器中獲取微信回傳給我們的code,通過這個code來請求access_token,通過access_token和openid獲取使用者基本資訊:

相關程式碼:

?

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

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

package com.xingshang.servlet;

import java.io.IOException;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import javax.servlet.ServletConfig;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.xingshang.util.AuthUtil;

import net.sf.json.JSONObject;

/**

* 回撥地址

* @author Administrator

*

*/

//@WebServlet("/callBack")

public class CallBackSerclet extends HttpServlet {

/**

*

*/

private static final long serialVersionUID = 1L;

private String dbUrl;

private String driverClassName;

private String userName;

private String passWord;

private Connection conn =null;

private PreparedStatement ps =null;

private ResultSet rs = null;

//初始化資料庫

@Override

public void init(ServletConfig config) throws ServletException {

//載入驅動

try {

this.dbUrl = config.getInitParameter("dbUrl");

this.driverClassName = config.getInitParameter("driverClassName");

this.userName = config.getInitParameter("userName");

this.passWord = config.getInitParameter("passWord");

Class.forName(driverClassName);

} catch (ClassNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

@Override

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//第二步:通過code換取網頁授權access_token

//從request裡面獲取code引數(當微信伺服器訪問回撥地址的時候,會把code引數傳遞過來)

String code = request.getParameter("code");

System.out.println("code:"+code);

//獲取code後,請求以下連結獲取access_token

+ "&secret=" + AuthUtil.APPSECRET

+ "&code=" + code

+ "&grant_type=authorization_code";

//通過網路請求方法來請求上面這個介面

JSONObject jsonObject = AuthUtil.doGetJson(url);

System.out.println("==========================jsonObject"+jsonObject);

//從返回的JSON資料中取出access_token和openid,拉取使用者資訊時用

String token = jsonObject.getString("access_token");

String openid = jsonObject.getString("openid");

// 第三步:重新整理access_token(如果需要)

// 第四步:拉取使用者資訊(需scope為 snsapi_userinfo)

+ "&openid=" + openid

+ "&lang=zh_CN";

//通過網路請求方法來請求上面這個介面

JSONObject userInfo = AuthUtil.doGetJson(infoUrl);

System.out.println(userInfo);

//第1種情況:使用微信使用者資訊直接登入,無需註冊和繫結

//    request.setAttribute("info", userInfo);

//直接跳轉

//    request.getRequestDispatcher("/index1.jsp").forward(request, response);

//第2種情況: 將微信與當前系統的賬號進行繫結(需將第1種情況和@WebServlet("/callBack")註釋掉)

//第一步,根據當前openid查詢資料庫,看是否該賬號已經進行繫結

try {

String nickname = getNickName(openid);

if(!"".equals(nickname)){

//已繫結

request.setAttribute("nickname", nickname);

request.getRequestDispatcher("/index2.jsp").forward(request, response);

}else{

//未繫結

request.setAttribute("openid", openid);

request.getRequestDispatcher("/login.jsp").forward(request, response);

}

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

//資料庫的查詢

public String getNickName(String openid) throws SQLException{

String nickName = "";

//建立資料庫連結

conn = DriverManager.getConnection(dbUrl, userName, passWord);

String sql = "select nickname from user where openid = ?";

ps = conn.prepareStatement(sql);

ps.setString(1, openid);

rs = ps.executeQuery();

while (rs.next()) {

nickName = rs.getString("nickname");

}

//關閉連結

rs.close();

ps.close();

conn.close();

return nickName;

}

//資料庫的修改(openid的繫結)

public int updateUser(String account,String password,String openid) throws SQLException{

//建立資料庫連結

conn = DriverManager.getConnection(dbUrl, userName, passWord);

String sql = "update user set openid = ? where account = ? and password = ?";

ps = conn.prepareStatement(sql);

ps.setString(1, openid);

ps.setString(2, account);

ps.setString(3, password);

int temp = ps.executeUpdate();

//關閉連結

rs.close();

ps.close();

conn.close();

return temp;

}

//post方法,用來接受登入請求

@Override

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String account = request.getParameter("account");

String password = request.getParameter("password");

String openid = request.getParameter("openid");

try {

int temp = updateUser(account, password, openid);

if(temp > 0){

String nickname = getNickName(openid);

request.setAttribute("nickname", nickname);

request.getRequestDispatcher("/index2.jsp").forward(request, response);

System.out.println("賬號繫結成功");

}else{

System.out.println("賬號繫結失敗");

}

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

login.jsp

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<meta name="viewport" content="width=device-width,initial-scale=1.0">

<title>Insert title here</title>

</head>

<body>

<form action="/WxAuth/wxCallBack" method="post">

<input type="text" name="account" />

<input type="password" name="password" />

<input type="hidden" name="openid" value="${openid }" />

<input type="submit" value="提交併繫結" />

</form>

</body>

</html>

index.jsp

?

1

2

3

4

5

6

7

8

9

10

11

12

13

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<meta name="viewport" content="width=device-width,initial-scale=1.0">

<title>Insert title here</title>

</head>

<body style="font-size: 40px; text-align: center;">

<a href="/WxAuth/wxLogin" rel="external nofollow" >微信公眾授權登入</a>

</body>

</html>

index1.jsp

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<meta name="viewport" content="width=device-width,initial-scale=1.0">

<title>Insert title here</title>

</head>

<body>

<div>登陸成功!</div>

<div>使用者暱稱:${info.nickname}</div>

<div>使用者頭像:<img style="text-align: top;" width="100" src="${info.headimgurl }"></div>

</body>

</html>

index2.jsp

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<meta name="viewport" content="width=device-width,initial-scale=1.0">

<title>Insert title here</title>

</head>

<body>

<div>登陸成功!</div>

<div>使用者暱稱:${nickname}</div>

</body>

</html>

最後附上需要的jar包

到此,微信授權登入成功,如果有執行問題請自行除錯,我這邊能正常執行的