微信授权步骤与详解 -- c#篇

注:这里不涉及界面操作,只介绍代码操作。

1.基本原理如下:

  

  从图上所知,第一步用户访问我们的网页,第二步我们后台跳转到微信授权页面,第三步用户点击授权,第四步微信重定向到第三方(我们后台)并且返回code,第五步请求accesstoken获取accesstoken和openid。

2.详细介绍

  第一步,用户访问我们网页。

例如,http://test.authorization.com/Main/TA

  第二步,我们后台跳转到微信授权页面。(第一次握手)

首先,我们跳转到微信页面,传参数为appid、redirectUrl、response_type、scope、state。

url为:"https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + redirectUrl + "&response_type=code&scope=snsapi_userinfo&state=" + state + "#wechat_redirect"

redirectUrl 为当前后台请求的url。代码如下:

string response_type = "code";//    返回类型,此时固定为:code
string scope = "snsapi_userinfo";//应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
string state = "state";//随便写,微信提供给我们的自定义参数。重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节
string url = string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type={2}&scope={3}&state={4}#wechat_redirect",appid, redirect_uri, response_type, scope, state);
hconHttpContextBase.Response.Redirect(url, true);//跳转到微信授权

   第三步,用户点击授权。

 

  第四步,微信重定向到第三方(我们后台)并且返回code(第二次握手)

微信重定向回我们后台时,会返回code,所以我们可以判断是否有code来确定微信是第几次握手。没code是第一次握手,有code是第二次握手。

  第五步,请求accesstoken获取accesstoken和openid

请求代码如下:

       string url = "https://api.weixin.qq.com/sns/oauth2/access_token";//请求的url
string sUrlpara = "appid=" + appId + "&secret=" + appSecret +
"&code=" + code + "&grant_type=authorization_code";//请求的参数
string jsonStr = Toos.HttpGet(url, sUrlpara);//网络get请求
//放回json解析
WeiXinAccessTokenResult result = new WeiXinAccessTokenResult();
if (jsonStr.Contains("errcode"))
{
WeiXinErrorMsg errorResult = new WeiXinErrorMsg();
errorResult = JsonHelper.ParseFormJson<WeiXinErrorMsg>(jsonStr);
result.ErrorResult = errorResult;
result.Result = false;
}
else
{
WeiXinAccessTokenModel model = new WeiXinAccessTokenModel();
model = JsonHelper.ParseFormJson<WeiXinAccessTokenModel>(jsonStr);
result.SuccessResult = model;
result.Result = true;
}

返回的json是:  

//正确的时候:
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE",
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" //这里一般没有返回,待定。
} //错误的时候:
{"errcode":40029,"errmsg":"invalid code"}

json解析的对象代码

    public class WeiXinAccessTokenResult
{
public WeiXinAccessTokenModel SuccessResult { get; set; }
public bool Result { get; set; } public WeiXinErrorMsg ErrorResult { get; set; }
} /// <summary>
/// 通过code获取access_token 请求成功的实体
/// </summary>
public class WeiXinAccessTokenModel
{
/// <summary>
/// 接口调用凭证
/// </summary>
public string access_token { get; set; }
/// <summary>
/// access_token接口调用凭证超时时间,单位(秒)
/// </summary>
public int expires_in { get; set; }
/// <summary>
/// 用户刷新access_token
/// </summary>
public string refresh_token { get; set; }
/// <summary>
/// 授权用户唯一标识
/// </summary>
public string openid { get; set; }
/// <summary>
/// 用户授权的作用域,使用逗号(,)分隔
/// </summary>
public string scope { get; set; }
} /// <summary>
/// 微信错误访问的情况
/// </summary>
public class WeiXinErrorMsg
{
/// <summary>
/// 错误编号
/// </summary>
public int errcode { get; set; }
/// <summary>
/// 错误提示消息
/// </summary>
public string errmsg { get; set; }
}

 

Tool.HttpGet方法

        public static string HttpGet(string Url, string postDataStr)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr);
request.Method = "GET";
request.ContentType = "text/html;charset=UTF-8"; HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
string retString = myStreamReader.ReadToEnd();
myStreamReader.Close();
myResponseStream.Close(); return retString;
}

3. 获取用户信息
  获取用户很简单,只需要传一个token以及openid获取用户的基本信息。

代码如下:

            string url = "https://api.weixin.qq.com/sns/userinfo";
string urlParam = "access_token=" + accessToken + "&openid=" + openId +
"⟨=zh_CN";
string jsonStr = Toos.HttpGet(url, urlParam); ;
WeiXinUserInfoResult result = new WeiXinUserInfoResult();
result.token = accessToken;
if (jsonStr.Contains("errcode"))
{
WeiXinErrorMsg errorResult = new WeiXinErrorMsg();
errorResult = JsonHelper.ParseFormJson<WeiXinErrorMsg>(jsonStr);
result.ErrorMsg = errorResult;
result.Result = false;
}
else
{
WXUserInfo userInfo = new WXUserInfo();
userInfo = JsonHelper.ParseFormJson<WXUserInfo>(jsonStr);
result.UserInfo = userInfo;
result.Result = true;
}

返回的json对象

{
"openid":" OPENID",
" nickname": NICKNAME,
"sex":"1",
"province":"PROVINCE"
"city":"CITY",
"country":"COUNTRY",
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
"privilege":[
"PRIVILEGE1"
"PRIVILEGE2"
],
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

解析json对象

    public class WeiXinUserInfoResult
{ public string token { get; set; }
/// <summary>
/// 微信用户信息
/// </summary>
public WXUserInfo UserInfo { get; set; }
/// <summary>
/// 结果
/// </summary>
public bool Result { get; set; }
/// <summary>
/// 错误信息
/// </summary>
public WeiXinErrorMsg ErrorMsg { get; set; } public override string ToString()
{
return string.Format("UserInfo: {0}, Result: {1}, ErrorMsg: {2}, token:{3}", UserInfo, Result, ErrorMsg, token);
}
}

备注:

添加jsonhelp类

    public class JsonHelper
{
public JsonHelper()
{
//
// TODO: Add constructor logic here
//
} /// <summary>
/// 把对象序列化 JSON 字符串
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="obj">对象实体</param>
/// <returns>JSON字符串</returns>
public static string GetJson<T>(T obj)
{
//记住 添加引用 System.ServiceModel.Web
/**
* 如果不添加上面的引用,System.Runtime.Serialization.Json; Json是出不来的哦
* */
DataContractJsonSerializer json = new DataContractJsonSerializer(typeof (T));
using (MemoryStream ms = new MemoryStream())
{
json.WriteObject(ms, obj);
string szJson = Encoding.UTF8.GetString(ms.ToArray());
return szJson;
}
} /// <summary>
/// 把JSON字符串还原为对象
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="szJson">JSON字符串</param>
/// <returns>对象实体</returns>
public static T ParseFormJson<T>(string szJson)
{
T obj = Activator.CreateInstance<T>();
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(szJson)))
{
DataContractJsonSerializer dcj = new DataContractJsonSerializer(typeof (T));
return (T) dcj.ReadObject(ms);
}
}
}

详细请看微信官方说明:

http://qydev.weixin.qq.com/wiki/index.php?title=WeixinJS%E6%8E%A5%E5%8F%A3

可以关注本人的公众号,多年经验的原创文章共享给大家。

微信授权步骤与详解 -- c#篇的更多相关文章

  1. Redis详解入门篇

    Redis详解入门篇 [本教程目录] 1.redis是什么2.redis的作者3.谁在使用redis4.学会安装redis5.学会启动redis6.使用redis客户端7.redis数据结构 – 简介 ...

  2. bt协议详解 基础篇(上)

    bt协议详解 基础篇(上) 最近开发了一个免费教程的网站,产生了仔细了解bt协议的想法,所以写了这一篇文章,后续还会写一些关于搜索和索引的东西,都是在开发这个网站的过程中学习到的技术,敬请期待. 1 ...

  3. java实现微信扫一扫详解

    java实现微信扫一扫详解 一.微信JS-SDK参数配置及查找 JS安全域名配置(查找:微信公众号里-公众号设置-功能设置页) 注:1.安全域名外网必须可以访问的到  2.域名不能有下划线  3.要将 ...

  4. Redis详解入门篇(转载)

    Redis详解入门篇(转载) [本教程目录] 1.redis是什么2.redis的作者3.谁在使用redis4.学会安装redis5.学会启动redis6.使用redis客户端7.redis数据结构 ...

  5. RocketMQ源码详解 | Producer篇 · 其二:消息组成、发送链路

    概述 在上一节 RocketMQ源码详解 | Producer篇 · 其一:Start,然后 Send 一条消息 中,我们了解了 Producer 在发送消息的流程.这次我们再来具体下看消息的构成与其 ...

  6. RocketMQ源码详解 | Broker篇 · 其四:事务消息、批量消息、延迟消息

    概述 在上文中,我们讨论了消费者对于消息拉取的实现,对于 RocketMQ 这个黑盒的心脏部分,我们顺着消息的发送流程已经将其剖析了大半部分.本章我们不妨乘胜追击,接着讨论各种不同的消息的原理与实现. ...

  7. bt协议详解 DHT篇(下)

    bt协议详解 DHT篇(下) 最近开发了一个免费教程的网站,产生了仔细了解bt协议的想法,这篇文章是bt协议详解系列的第三篇,后续还会写一些关于搜索和索引的东西,都是在开发这个网站的过程中学习到的技术 ...

  8. bt协议详解 DHT篇(上)

    bt协议详解 DHT篇(上) 最近开发了一个免费教程的网站,突然产生了仔细了解bt协议的想法,这篇文章是bt协议详解系列的第三篇,后续还会写一些关于搜索和索引的东西,都是在开发这个网站的过程中学习到的 ...

  9. IIS负载均衡-Application Request Route详解第二篇:创建与配置Server Farm(转载)

    IIS负载均衡-Application Request Route详解第二篇:创建与配置Server Farm 自从本系列发布之后,收到了很多的朋友的回复!非常感谢,同时很多朋友问到了一些问题,有些问 ...

随机推荐

  1. (python)图片处理Pillow模块的使用

    Pillow中最重要的类就是Image,该类存在于同名的模块中.可以通过以下几种方式实例化:从文件中读取图片,处理其他图片得到,或者直接创建一个图片. 还有一个类为ImageDraw,用来画图. 1. ...

  2. K/3 Cloud开发之旅 -- 主页自定义篇(一)

    如果说我们要进行主页自定义篇,首先涉及到的就是登陆的自定义,那么如何进行登录界面的自定义呢 其实登陆界面自定义主要就是图片的替换 ,那么我们就看下登陆界面的图片的组成 登录页面底图有两部分组成,一个是 ...

  3. nodejs研究笔记

    首先呢,安装 1:安装mongodb-win32-x86_64-3.2.5-signed.msi 2:手动创建目录 如 C:\data\db 及 C:\data\dbConf 3:管理员身份运行 cm ...

  4. 一些不起眼但非常有用的 Vim 命令

    保存文件并退出 说起来有些惭愧,我也是最近才学到这个命令

  5. 【转载】【树形DP】【数学期望】Codeforces Round #362 (Div. 2) D.Puzzles

    期望计算的套路: 1.定义:算出所有测试值的和,除以测试次数. 2.定义:算出所有值出现的概率与其乘积之和. 3.用前一步的期望,加上两者的期望距离,递推出来. 题意: 一个树,dfs遍历子树的顺序是 ...

  6. 【分块打表】bzoj1026 [SCOI2009]windy数

    #include<cstdio> using namespace std; #define BN 380000 const int table[]={0,79595,158824,2021 ...

  7. CodeForces 743C Vladik and fractions (数论)

    题意:给定n,求三个不同的数满足,2/n = 1/x + 1/y + 1/z. 析:首先1是没有解的,然后其他解都可以这样来表示 1/n, 1/(n+1), 1/(n*(n+1)),这三个解. 代码如 ...

  8. html或者jsp页面引用jar包中的js文件

    一,页面上引用jar包中的js文件的方法 使用java web框架AppFuse的时候发现,jquery.bootstrap等js框架都封装到jar包里面了.这些js文件通过一个wro4j的工具对其进 ...

  9. zmq中zmq_poll()函数介绍

    功能: 查看指定的多个socket上哪些socket发生了指定的事件, 事件有: ZMQ_POLLIN: 有消息到来 ZMQ_POLLOUT: 当前无阻塞可以发送消息 ZMQ_POLLERR: 只对标 ...

  10. linux 第一题 计算题

    #!/bin/bash echo "输入第一个数字" read A b= ]] do && [[ ${A} != *[!]* ]] then echo " ...