UnionID
同一用户、同一微信平台下的不同应用unionid相同

静默授权
1. snsapi_base为scope的网页授权
2. 已进入本公众号的网页授权页snsapi_userinfo

网页授权4步:
1. 用户同意授权,获取code
2. 通过code换取网页授权access_token
3. 刷新access_token(如有需要)
4. scope为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

appid 公众号的唯一标识
redirect_uri 授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理
response_type 返回类型,即code
scope 应用授权作用域,
snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),
snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息 )
state 重定向后会带上state参数(非必须)
wechat_redirect 无论直接打开还是做页面302重定向时候,必须带此参数

如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE(5分钟未被使用自动过期)

secret 公众号的appsecret
grant_type 即authorization_code

第二步,通过code换取网页授权access_token

如果scope为snsapi_token,获取access_token同时获取openid。

获取code后,请求以下链接获取access_token:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

返回数据:

{
“access_token”:“ACCESS_TOKEN”, // 网页授权接口调用凭证
“expires_in”:7200,
“refresh_token”:“REFRESH_TOKEN”, // 用户刷新access_token
“openid”:“OPENID”,
“scope”:“SCOPE”
}

第三步:刷新access_token(如果需要)

获取第二步的refresh_token后,请求以下链接获取access_token:
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN

第四步:拉取用户信息(需scope为 snsapi_userinfo)

如果scope为 snsapi_userinfo,通过access_token和openid拉取用户信息

http:GET(请使用https协议)
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

返回数据:

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

检验授权凭证(access_token)是否有效

http:GET(请使用https协议)
https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID

相关链接:
1 微信网页开发-网页授权

部分封装方法如下:

const (redirectOauthURL       = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect"webAppRedirectOauthURL = "https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect"webAccessTokenURL      = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"refreshAccessTokenURL  = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s"userInfoURL            = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN"checkAccessTokenURL    = "https://api.weixin.qq.com/sns/auth?access_token=%s&openid=%s"accessTokenURL         = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"getTicketURL           = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi"
)// 获取redirectOauthURL链接。其在微信中跳转后可以获取code
// 因为微信转码会造成部分链接参数丢失的情况,使用urlEncode对链接进行处理
func RedirectOauthUrl(appID, redirectUrl string) string {if appID ==  "" || redirectUrl == "" {return ""}// url encodev := url.Values{}v.Add("redirectUrl", redirectUrl)    // 添加mapencodeUrl := v.Encode()encodeUrl = strings.TrimLeft(encodeUrl, "redirectUrl=") //去掉url中多余的字符串urlStr := fmt.Sprintf(redirectOauthURL, appID, encodeUrl, "snsapi_userinfo", "")return urlStr
}// 网页授权access_token
type ResWebAccessToken struct {AccessToken  string `json:"access_token"`ExpiresIn    int    `json:"expires_in"`RefreshToken string `json:"refresh_token"`Scope        string `json:"scope"`Openid       string `json:"openid"`Unionid      string `json:"unionid"`Errcode      int    `json:"errcode"`Errmsg       string `json:"errmsg"`
}// 获取网页授权access_token
func GetWebAccessToken(appID, secret, code string) (res ResWebAccessToken, err error) {urlStr := fmt.Sprintf(webAccessTokenURL, appID, secret, code)body, err := util.HttpGet(urlStr)if err != nil {return}err = json.Unmarshal(body, &res)if err != nil {return}if res.Errcode != 0 {err = fmt.Errorf("GetWebAccessToken error : errcode=%v , errmsg=%v", res.Errcode, res.Errmsg)return}return
}type WxUserInfo struct {ID         int        `json:"id"`Openid     string     `json:"openid"`Nickname   string     `json:"nickname"`Headimgurl string     `json:"headimgurl"`Sex        int        `json:"sex"`Province   string     `json:"province"`City       string     `json:"city"`Country    string     `json:"country"`Name       string     `json:"name"`Mobile     string     `json:"mobile"`Address    string     `json:"address"`CreatedAt  time.Time  `json:"created_at"`UpdatedAt  time.Time  `json:"updated_at"`DeletedAt  *time.Time `json:"deleted_at"`Errcode    int        `json:"errcode"`Errmsg     string     `json:"errmsg"`
}func GetUserInfo(accessToken, openID string) (res WxUserInfo, err error) {urlStr := fmt.Sprintf(userInfoURL, accessToken, openID)body, err := util.HttpGet(urlStr)if err != nil {return}err = json.Unmarshal(body, &res)if err != nil {return}if res.Errcode != 0 {err = fmt.Errorf("GetUserInfo error : errcode=%v , errmsg=%v", res.Errcode, res.Errmsg)return}return
}// 普通access_token
type ResAccessToken struct {AccessToken string `json:"access_token"`ExpiresIn   int    `json:"expires_in"`Errcode     int    `json:"errcode"`Errmsg      string `json:"errmsg"`
}// 获取普通access_token
func GetAccessToken(appID, secret string) (res ResAccessToken, err error) {urlStr := fmt.Sprintf(accessTokenURL, appID, secret)body, err := util.HttpGet(urlStr)if err != nil {return}err = json.Unmarshal(body, &res)if err != nil {return}if res.Errcode != 0 {err = fmt.Errorf("GetUserAccessToken error : errcode=%v , errmsg=%v", res.Errcode, res.Errmsg)return}return
}type resTicket struct {Ticket    string `json:"ticket"`ExpiresIn int    `json:"expires_in"`Errcode   int    `json:"errcode"`Errmsg    string `json:"errmsg"`
}func GetTicket(accessToken string) (res resTicket, err error) {urlStr := fmt.Sprintf(getTicketURL, accessToken)body, err := util.HttpGet(urlStr)if err != nil {return}err = json.Unmarshal(body, &res)if err != nil {return}if res.Errcode != 0 {err = fmt.Errorf("getTicket Error : errcode=%d , errmsg=%s", res.Errcode, res.Errmsg)return}return
}

golang_微信公众号网页授权相关推荐

  1. 微信公众号网页授权--前端获取code及用户信息(vue)

    前段时间开发微信公众号网页授权,虽然网上已经有很多关于这方面的博客或者教程,但是第一次开发还是遇到挺多坑的,以下分享一下我的踩坑填坑之路. 一.测试号相关配置 首先在你公司申请的测试号上配置好相关信息 ...

  2. 微信公众号网页授权--前端获取code及用户信息(vue)【简单详细版】

    嗨喽大家好,前段时间开发微信公众号网页授权,虽然网上已经有很多关于这方面的博客或者教程,但是第一次开发还是遇到挺多坑的,以下分享一下我的遇到的一些问题的见解,希望对你们有帮助. 一.测试号相关配置 首 ...

  3. 微信公众号网页授权思路解析及具体代码

    微信公众号网页授权思路解析及具体代码 微信开发文档 实现方式也是两种: 1.静默授权登录 授权登录以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静 ...

  4. 微信公众号网页授权,获取用户信息以及openid -- PHP后台

    微信公众号网页授权,获取用户信息以及openid 这几天做项目,想通过公众号的appid获取用户的openid就,然后在网上查资料,问朋友,最后找到了方法,就是这个网页授权. 起初一直很蒙,这个怎么弄 ...

  5. 微信公众号网页授权时序图

    微信公众号网页授权时序图 公众号网页授权时序图

  6. 微信公众号网页授权登录的超简单实现步骤

    微信开放平台为第三方移动程序提供分享.传播的接口, 使用户可将第三方程序的内容发布给好友或分享至朋友圈, 下面这篇文章主要给大家介绍了关于微信公众号网页授权登录的超简单实现方法, 需要的朋友可以参考下 ...

  7. 微信公众号网页授权40163问题【php】

    微信公众号网页授权40163问题 tp5为例,emmmm-一直报40163或40029问题,翻遍了各大网站都没找到合适我的办法. 如图: 解决之后如图: 因为重定向所以请求了两次code,所以一直报4 ...

  8. 微信公众号网页授权代码优化过程(一)

    2019独角兽企业重金招聘Python工程师标准>>> 第一次更新 写本系列博客的主要原因是,我在处理一个微信公众号项目时要做一个网页授权的操作(官方地址是https://mp.we ...

  9. php微信授权没有code返回,解决关于微信公众号网页授权获取code参数的问题

    解决关于微信公众号网页授权获取code参数的问题 发布时间:2018-07-24 23:21, 浏览次数:3327 , 标签: code * 在微信网页授权过程中,需要获取code参数,因为我用的是公 ...

最新文章

  1. php excel 追加写入,phpexcel写入追加已有的excel文件
  2. 几个我收藏的经典网站
  3. 【学习笔记】git 使用文档
  4. 剑指offer_第11题_二进制中1的个数
  5. 计算机音乐刚好遇见你乐谱,《刚好遇见你》曲谱_刚好遇见你乐谱
  6. 《博士五年总结》及我其它过去的博客文章
  7. rsync 配置详解
  8. 前端学习(3335):ant design中按钮尺寸的大小
  9. visual studio code怎么改成中文?Visual Studio Code Insiders for Mac中文修复版
  10. 如何运用模板之家做html,Flask框架如何使用HTML模板
  11. OneAPM Cloud Test——系统性能监控神器 1
  12. 与我们息息相关的internet服务(2)---WWW服务
  13. Hyperspace初体验:Delta Lake表索引
  14. Linux(Ubuntu 22.04)虚拟机共享主机上的文件夹
  15. Codeforces Round #612 (Div. 1) A. Garland(dp动态规划)
  16. gis生成道路中心线_ArcGIS方法-利用到路面提取道路中心线地方法
  17. switch语句练习题
  18. 学习andriod开发之 自己开发短信发送软件
  19. linux命令后台执行方式
  20. 设计一个Person类,包含name、age、sex属性以及对这些属性操作的方法。实现并测试这个类。根据类的封装性要求,把name、age、sex声明为私有的数据成员,声明公有的成员函数Regist

热门文章

  1. educoder:实验十一 函数
  2. iOS-APP性能测试
  3. 基于大数据的精准营销与应用场景
  4. 文本记录任意时刻的ping值
  5. 教你写Makefile
  6. C#窗体Winform,如何嵌入图片添加图片,使用图片资源?
  7. 如何在Visual Paradigm中创建流程图?
  8. 数字接龙 用计算机完成318,微信报名接龙数字如何排列对齐传递
  9. 刷 LeetCode 吃力正常吗?
  10. 解决在x86平台装openwrt旁路由大流量断网问题(intel网卡驱动bug问题)