例: C#.NET を使用して WeChat 公式アカウントの開発方法を教える (22) -- Web ページで OAuth を介してユーザーの openid を取得する

パート 1: 理論

ユーザーが特定の公式アカウントをフォローせず、WeChat で公式アカウントの Web サーバー上の Web ページを開くだけの場合、ビジネス ロジックを実装するためにユーザーの openID とユーザーの WeChat 情報を取得するにはどうすればよいでしょうか? この記事では、WeChat ユーザーを取得するための Web ページ認証 OAuth の重要な情報について説明します。まず概念を理解しましょう。

Webページの認証

ユーザーが WeChat クライアントでサードパーティの Web ページにアクセスすると、公式アカウントは WeChat Web ページの認証メカニズムを通じてユーザーの基本情報を取得し、ビジネス ロジックを実現します。

WeChat Webページの認証機能調整に関するお知らせ

機能の使用をさらに標準化し、ユーザーの正当な権利と利益を保護するために、プラットフォームは WeChat Web ページの認証機能を調整します。 開発者が Web ページ上で非標準的な使用で snsapi_userinfo Web ページの認証を開始すると、WeChat はデフォルトで基本的なブラウジング用に Web ページのスナップショット ページ モードを開きます。 容量調整は2022年7月12日24:00に実施されます。詳細については、クリックして元の発表「WeChat Web ページの認証機能調整の発表」を参照してください。

Web ページのコールバック ドメイン名の承認に関する手順

  1. WeChat 公式アカウントがユーザーの Web ページ認証をリクエストする前に、開発者は公式プラットフォームの公式 Web サイトにアクセスして、「開発 - インターフェイス許可 - Web ページ サービス - Web ページ アカウント - Web ページ認証」の構成オプションで認証コールバック ドメイン名を変更する必要があります。公式プラットフォームの公式サイトにある「ユーザー基本情報の取得」を参照してください。ここで入力するのはURLではなくドメイン名(文字列)ですので、http://などのプロトコルヘッダは付加しないでください。
  2. 認可コールバック ドメイン名の構成仕様は完全なドメイン名です。たとえば、Web ページの認可が必要なドメイン名は www.qq.com です。構成後、このドメイン名のページは http://www になります。 .qq.com/music.html、http://www. qq.com/login.html は両方とも OAuth2.0 認証を実行できます。ただし、http://pay.qq.com、http://music.qq.com、http://qq.com は OAuth2.0 認証を実行できません。

Webページ認可の2つのスコープの違いについての説明

  1. snsapi_base をスコープとして開始された Web ページの承認は、ページに入るユーザーの openid を取得するために使用され、サイレントに承認され、自動的にコールバック ページにジャンプします。ユーザーが認識するのは、コールバック ページ (多くの場合ビジネス ページ) に直接入ることです。
  2. スコープとして snsapi_userinfo で開始された Web ページの認証は、ユーザーの基本情報を取得するために使用されます。ただし、この種の認可にはユーザーの手動による同意が必要であり、ユーザーは同意しているため、認可後は特に意識することなくユーザーの基本情報を取得できる。
  3. ユーザー管理インターフェースの「ユーザー基本情報取得インターフェース」は、ユーザーと公式アカウントがメッセージやり取りやフォローイベントプッシュを行った後、ユーザーのOpenIDに基づいてユーザーの基本情報を取得するものです。他の WeChat インターフェイスを含むこのインターフェイスでは、ユーザー (つまり、openid) が公式アカウントを正常に呼び出す前に、そのアカウントをフォローする必要があります。

Webページ認可のaccess_tokenと通常のaccess_tokenの違いについて

  1. WeChat Web ページの認証は OAuth2.0 メカニズムを通じて実現され、ユーザーが公式アカウントを認証した後、公式アカウントは固有のインターフェイス呼び出し証明書 (Web ページ認証 access_token) を取得でき、認証後のインターフェイス呼び出しは OAuth2.0 メカニズムを通じて行うことができます。 Web ページの認証 access_token. 基本的なユーザー情報の取得など。
  2. 他の WeChat インターフェイスの場合は、基本サポートの「access_token の取得」インターフェイスを通じて取得した通常の access_token を呼び出す必要があります。

特殊なシナリオでのサイレント認証について

  1. 上で述べたように、スコープとして snsapi_base を使用した Web ページの認可の場合、それはサイレントに認可され、ユーザーは何も認識しません。
  2. 公式アカウントをフォローしているユーザーの場合、公式アカウントのセッションやカスタムメニューから公式アカウントのWebページの認証ページに入ると、スコープが snsapi_userinfo であってもサイレント認証となり、ユーザーには認識されません。

開発ガイド

Web ページの認証プロセスは 4 つのステップに分かれています。

  1. 認証ページにアクセスして認証に同意し、コードを取得するようにユーザーを誘導します。
  2. Web ページ認可 access_token の交換コード (基本サポートの access_token とは異なります)
  3. 必要に応じて、開発者は Web ページを更新して access_token を認証し、期限切れを回避できます。
  4. Web ページ認証 access_token および openid を通じて基本的なユーザー情報を取得します (UnionID メカニズムをサポート)

ステップ 1: ユーザーはコードを承認して取得することに同意します。

WeChat パブリック アカウントに承認スコープ (scope パラメーター) が設定されていることを前提として (認証されたサービス アカウントには、デフォルトでスコープ パラメーターに snsapi_base および snsapi_userinfo 権限が付与されています)、フォロワーに次のページを開くように誘導します。

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

「このリンクにアクセスできません」というプロンプトが表示された場合は、パラメーターが正しく入力されていないか、スコープ パラメーターに対応する認可スコープ権限があるかどうかを確認してください。

特に注意してください: 承認操作のセキュリティ レベルが高いため、承認リクエストが開始されると、WeChat は承認リンクに対して定期的な強力な一致検証を実行します。リンクのパラメーターの順序が間違っている場合、承認ページは表示されません。正常にアクセスできるようになります。

参考リンク (このリンクを WeChat クライアントで開いて体験してください):

スコープは snsapi_base です。

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=https%3A%2F%2Fchong.qq.com%2Fphp%2Findex.php%3Fd%3D%26c%3DwxAdapter%26m% 3DmobileDeal%26showwxpaytitle%3D1%26vb2ctag%3D4_2030_5_1194_60&response_type=code&scope=snsapi_base&state=123#wechat_redirect

スコープは snsapi_userinfo です。

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect

 

ステップ 2: Web ページ認証 access_token のコードを交換する

まず最初に、ここでコードを通じて交換されるのは特別な Web ページ認証 access_token であり、基本サポートの access_token とは異なることに注意してください (access_token は他のインターフェイスを呼び出すために使用されます)。公式アカウントは、以下のインターフェースを通じて Web ページ認可 access_token を取得できます。Web ページ認可のスコープが snsapi_base の場合、このステップで Web ページ認可 access_token が取得され、openid も取得され、snsapi_base 形式の Web ページ認可プロセスはここで終了します。

特に注意してください: 公式アカウントのシークレットと取得した access_token は非常に高いセキュリティ レベルを持つため、サーバー上にのみ保存する必要があり、クライアントに渡すことは許可されません。access_token の更新や access_token を介したユーザー情報の取得などの後続のステップもサーバーから開始する必要があります。

リクエストメソッド

コードを取得した後、次のリンクをリクエストして access_token を取得します。

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

 

ステップ 3: access_token を更新する (必要な場合)

access_token の有効期限は短いため、access_token の有効期限が切れた場合は、refresh_token で更新できます (refresh_token の有効期限は 30 日間です)。

リクエストメソッド

2 番目のステップでfresh_token を取得した後、次のリンクをリクエストして access_token を取得します。

https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN

 

ステップ 4: ユーザー情報を取得する (スコープが snsapi_userinfo である必要があります)

Web ページの認可スコープが snsapi_userinfo の場合、開発者はこの時点で、access_token と openid を通じてユーザー情報を取得できます。

リクエストメソッド

http: GET (https プロトコルを使用してください):

https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

すべてが正常な場合、返されるユーザー情報フィールドは次のとおりです。

 

 

パート 2: 戦闘

1. まず専用のクラスを準備し、ソース コードを直接アップロードします。

/*
*类名:QinMingWeixinOAuth
*归属:QinMing.WeixinOAuth命名空间
*用途:通过网页OAuth方式获取用户openid和access_token,进而可以获取微信用户的头像、昵称等信息
*作者:
*日期:8
*/

using System;
using System.Web;
using System.Net;
using System.IO;
using System.Text;
using Newtonsoft.Json;  
using Newtonsoft.Json.Converters; 
using Newtonsoft.Json.Linq; 
using QinMing.Config;

namespace QinMing.WeixinOAuth
{
    public  class QinMingWeixinOAuth : System.Web.UI.Page
    {
		
		/// <summary>
        /// 获取CODE,后期用于获取微信用户openid,静默,不需要用户确认
        /// </summary>
		public string GetCodeBase(string appid, string redirect_url)
		{
			var state = "QinMing" + DateTime.Now.Millisecond;
			string RedirectUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?" 
			    + "appid=" + appid 
				+ "&redirect_uri=" + redirect_url
				+ "&response_type=code&scope=snsapi_base"
				+ "&state=" + state + "#wechat_redirect";
			
			return RedirectUrl;
		}
		
		/// <summary>
        /// 用CODE换取openid,适用于获取用户openid,在scope=snsapi_base使用
        /// </summary>
		public string GetOpenId(string code)
	    {
			string appid = QinMingConfig.Weixin_AppId;
			string secret = QinMingConfig.Weixin_AppSecret;
			string strResult="";
			string openid="";
			string strurl="https://api.weixin.qq.com/sns/oauth2/access_token?appid="
			    + appid + "&secret="
				+ secret + "&code="
				+ code + "&grant_type=authorization_code";
			try
			{
				HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strurl);
				HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
				Stream myStream = HttpWResp.GetResponseStream();
				StreamReader sr = new StreamReader(myStream, Encoding.UTF8);
				StringBuilder strBuilder = new StringBuilder();
				while (-1 != sr.Peek())
				{
					strBuilder.Append(sr.ReadLine());
				}
				strResult = strBuilder.ToString();
				
				JObject obj = (JObject)JsonConvert.DeserializeObject(HttpUtility.UrlDecode(strResult));
				openid = obj["openid"].ToString().Replace("\"", "");
				return openid;
			}
			catch
			{
			    strResult = "err";
				return strResult;
			}
	    }
		
		/// <summary>
        /// 获取CODE,后期用于获取微信用户信息,需要用户确认;与上面GetCodeBase的差异只是scope=snsapi_userinfo部分
        /// </summary>
		public string GetCodeUserInfo(string appid, string redirect_url)
		{
			var state = "QinMing" + DateTime.Now.Millisecond;
			string RedirectUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?" 
			    + "appid=" + appid 
				+ "&redirect_uri=" + redirect_url
				+ "&response_type=code&scope=snsapi_userinfo"
				+ "&state=" + state + "#wechat_redirect";
			
			return RedirectUrl;
		}
		
		/// <summary>
        /// 用CODE换取openid和AccessToken,适用于获取用户信息,在scope=snsapi_userinfo使用,切忌只能用在服务器端使用,不能传递到客户端,高风险
        /// </summary>
		public string GetOpenIdAndAccessToken(string code)
	    {
            string appid = QinMingConfig.Weixin_AppId;
			string secret = QinMingConfig.Weixin_AppSecret;
			string strResult="";
			string openid="";
			string access_token="";
			string strurl="https://api.weixin.qq.com/sns/oauth2/access_token?appid="
			    + appid + "&secret="
				+ secret + "&code="
				+ code + "&grant_type=authorization_code";
			try
			{
				HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strurl);
				HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
				Stream myStream = HttpWResp.GetResponseStream();
				StreamReader sr = new StreamReader(myStream, Encoding.UTF8);
				StringBuilder strBuilder = new StringBuilder();
				while (-1 != sr.Peek())
				{
					strBuilder.Append(sr.ReadLine());
				}
				strResult = strBuilder.ToString();
				
				JObject obj = (JObject)JsonConvert.DeserializeObject(HttpUtility.UrlDecode(strResult));
				openid = obj["openid"].ToString().Replace("\"", "");
				access_token = obj["access_token"].ToString().Replace("\"", "");
				return openid + "|" + access_token;
			}
			catch
			{
			    strResult = "err";
				return strResult;
			}
			
	    }
		
		/// <summary>
        /// 获取用户信息,包含头像和昵称等
        /// </summary>
		public JObject GetUserInfo(string open_id, string access_token)
	    {
			string strResult = "";
			string strurl="https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + open_id + "&lang=zh_CN";
			try
			{
				HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strurl);
				HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
				Stream myStream = HttpWResp.GetResponseStream();
				StreamReader sr = new StreamReader(myStream, Encoding.UTF8);
				StringBuilder strBuilder = new StringBuilder();
				while (-1 != sr.Peek())
				{
					strBuilder.Append(sr.ReadLine());
				}
				strResult = strBuilder.ToString();

				//更新weixin_user_info表中微信用户信息
				JObject tmpobj = (JObject)JsonConvert.DeserializeObject(HttpUtility.UrlDecode(strResult));
				QinMingToolsDB.UpdateTable("update weixin_user_info set nickname='" + tmpobj["nickname"].ToString().Replace("\"", "") + "',"
				    + "headimgurl='" + tmpobj["headimgurl"].ToString().Replace("\"", "") + "',"
					+ "province='" + tmpobj["province"].ToString().Replace("\"", "") + "',"
					+ "city='" + tmpobj["city"].ToString().Replace("\"", "") + "',"
					+ "country='" + tmpobj["country"].ToString().Replace("\"", "") + "',"
					+ "sex='" + tmpobj["sex"].ToString().Replace("\"", "") + "' "
				    + " where openid='" + open_id + "'");
			}
			catch
			{
				strResult = "err";
			}
			JObject obj = (JObject)JsonConvert.DeserializeObject(HttpUtility.UrlDecode(strResult));
			return obj;
	    }
		/*
		//正确返回时JObject格式如下
		{   
			"openid": "OPENID",
			"nickname": NICKNAME,
			"sex": 1,
			"province":"PROVINCE",
			"city":"CITY",
			"country":"COUNTRY",
			"headimgurl":"https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
			"privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
			"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
		}
		*/

	}
	
	
}

2. WeChat ユーザーの openid のみを取得します

使用方法: http://www.xxxx.com/weixin/RedirectWithOpenIdFirst.aspx?final_url=myweb.aspx

このようにして、myweb.aspx を開くと、WeChat ユーザーの openid パラメータが含まれます。

RedirectWithOpenIdFirst.aspx ソース コード:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="RedirectWithOpenIdFirst.aspx.cs" Inherits="Jjlm.RedirectWithOpenIdFirst" %>

RedirectWithOpenIdFirst.aspx.cs ソース コード:

using System;
using System.Web;
using QinMing.Config;
using QinMing.WeixinOAuth;

namespace Jjlm
{
	public partial class RedirectWithOpenIdFirst : System.Web.UI.Page
	{
		protected void Page_Load(object sender, EventArgs e)
		{
			string final_url = Request.QueryString["final_url"]; 
			string appid = QinMingConfig.Weixin_AppId;
			string redirect_url = QinMingConfig.Url_WebServer + "/weixin/RedirectWithOpenIdSecond.aspx" + "?final_url=" + final_url;
			QinMingWeixinOAuth oauth = new QinMingWeixinOAuth();
			string newurl = oauth.GetCodeBase(appid, redirect_url);
			Response.Redirect(newurl);
		}
	}
}   

RedirectWithOpenIdSecond.aspx ソース コード:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="RedirectWithOpenIdSecond.aspx.cs" Inherits="Jjlm.RedirectWithOpenIdSecond" %>

RedirectWithOpenIdSecond.aspx.cs ソース コード:

using System;
using System.Web;
using QinMing.WeixinOAuth;

namespace Jjlm
{
	public partial class RedirectWithOpenIdSecond : System.Web.UI.Page
	{
		
		protected void Page_Load(object sender, EventArgs e)
		{
			string final_url = Request.QueryString["final_url"]; 
			string code = Request.QueryString["code"]; 
			QinMingWeixinOAuth oauth=new QinMingWeixinOAuth();

			//仅获取openid
			string open_id  = oauth.GetOpenId(code);
			Response.Redirect(final_url + "?open_id=" + open_id);
		}

	}
}   

3. WeChat ユーザーの openid、ニックネーム、アバター、その他の情報を取得します

使用方法: http://www.xxxx.com/Coalition/OAuthOpenidAndUserinfoFirst.aspx?final_url=myweb.aspx

このようにして、myweb.aspx を開くと、WeChat ユーザーの openid パラメーターが取り込まれ、ニックネーム Nickname とアバター head_img_url パラメーターも同時に取り込まれます。

OAuthOpenidAndUserinfoFirst.aspx ソース コード:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="OAuthOpenidAndUserinfoFirst.aspx.cs" Inherits="Coalition.OAuthOpenidAndUserinfoFirst" %>

OAuthOpenidAndUserinfoFirst.aspx.cs ソース コード:

using System;
using System.Web;
using QinMing.Config;
using QinMing.WeixinOAuth;

namespace Coalition
{
	public partial class OAuthOpenidAndUserinfoFirst : System.Web.UI.Page
	{
		protected void Page_Load(object sender, EventArgs e)
		{
			string final_url = Request.QueryString["final_url"]; 
			string appid = QinMingConfig.Weixin_AppId;
			string redirect_url = QinMingConfig.Url_WebServer + "/Coalition/OAuthOpenidAndUserinfoSecond.aspx" + "?final_url=" + final_url;
			QinMingWeixinOAuth oauth = new QinMingWeixinOAuth();
			string newurl = oauth.GetCodeUserInfo(appid, redirect_url);
			Response.Redirect(newurl);
		}
	}
}   

OAuthOpenidAndUserinfoSecond.aspx ソース コード:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="OAuthOpenidAndUserinfoSecond.aspx.cs" Inherits="Coalition.OAuthOpenidAndUserinfoSecond" %>

OAuthOpenidAndUserinfoSecond.aspx.cs ソース コード:

using System;
using System.Web;
using Newtonsoft.Json;  
using Newtonsoft.Json.Converters; 
using Newtonsoft.Json.Linq; 
using QinMing.WeixinOAuth;
using QinMing.Tools;

namespace Coalition
{
	public partial class OAuthOpenidAndUserinfoSecond : System.Web.UI.Page
	{
		
		protected void Page_Load(object sender, EventArgs e)
		{
			string final_url = Request.QueryString["final_url"]; 
			string code = Request.QueryString["code"]; 
			QinMingWeixinOAuth oauth=new QinMingWeixinOAuth();

			//获取openid和access_token
			string openid_accesstoken  = oauth.GetOpenIdAndAccessToken(code);
			//QinMingTools.WriteLog("oauth2.0获取信息测试", openid_accesstoken);
			
			//获取用户头像链接和昵称
			string[] array = openid_accesstoken.Split(new Char[] { '|' });
			string open_id = array[0];
			string access_token = array[1];

			JObject obj = oauth.GetUserInfo(open_id, access_token);
			string head_img_url = obj["headimgurl"].ToString().Replace("\"", "");
			string nickname = obj["nickname"].ToString().Replace("\"", "");
			Response.Redirect(final_url + "?open_id=" + open_id + "&head_img_url=" + head_img_url + "&nickname=" + nickname);
			
		}

	}
}   

重要な注意事項: Web ページを通じて WeChat ユーザーの openid を取得することに加えて、オンライン販売などのビジネス ロジックの実装に加えて、一般的なアプリケーションには投票と勧誘、パートナー、分裂コミュニケーションが含まれます。

おすすめ

転載: blog.csdn.net/daobaqin/article/details/126861247
おすすめ