微信第三方登录 -- (PC端+移动端)

微信第三方登录 -- (PC端+移动端)

一、前言

一. 什么是第三方登录

所谓的第三方登录,是说基于用户在第三方平台上已有的账号和密码来快速完成己方应用的登录或者注册的功能。而这里的第三方平台,一般是已经拥有大量用户的平台,国外的比如Facebook,Twitter等,国内的比如微博、微信、QQ等。

二. 为什么要用第三方登录

第三方登录之所以会被较为广泛地在产品设计上使用,是因为它有以下几个优点:

(1)对普通用户

相比于本地注册,第三方登录一般来说比较方便、快捷,能够显著降低用户的注册和登录成本,方便用户实现快捷登录或注册。不用费尽心思地应付本地注册对账户名和密码的各种限制,如果不考虑昵称的重复性要求,几乎可以直接一个账号走遍天下,再也不用在大脑或者什么地方记住N多不同的网站或App的账号和密码,整个世界一下子清静了。在第一次绑定成功之后,之后用户便可以实现一键登录,使得后续的登录操作比起应用内的登录来容易了很多。对于某些喜欢社交,并希望将更多自己的生活内容展示给朋友的人来说,第三方登录可以实现把用户在应用内的活动同步到第三方平台上,省去了用户手动发布动态的麻烦。但对于某些比较注重个人隐私的用户来说,则会有一些担忧,所以说这个优点是有前提的。

(2)对应用

因为降低了用户的注册或登录成本,从而减少由于本地注册的繁琐性而带来的隐形用户流失,最终提高注册转化率。对于某些应用来说,使用第三方登录完全可以满足自己的需要,因此不必要设计和开发一套自己的账户体系。通过授权,可以通过在第三方平台上分享用户在应用内的活动在第三方平台上宣传自己,从而增加产品知名度。通过授权,可以获得该用户在第三方平台上的好友或粉丝等社交信息,从而后续可以针对用户的社交关系网进行有目的性的营销宣传,为产品的市场推广提供另一种渠道。

(3)对第三方

增加用户对平台的依赖,用户越多使用本平台的第三方登录,就代表着平台对该用户的粘性越高。获得更广泛的影响力,只要用户使用提供第三方登录的应用,那么这个提供第三方登录的品牌就会被用户浏览,有利于对平台的拉新和促活。

三. 使用第三方登录要注意的地方

任何事物都是有两面性的,尽管第三方登录具有以上所述的优点,但同时也存在着一定的问题需要注意,供大家参考:

(1)对用户

一旦自己的第三方账户出现问题,比如被第三方平台封号,或者账号被盗,则会发生相应的应用内数据丢失或者数据泄露。这个时候即使注册一个新账户,之前在应用内所有的记录也是无法恢复的。

(2)对应用

对于有自己本地注册需求,并且提供第三方登录的应用而言,需要考虑第三方账号和本地账号的对接问题,产品需要设计对接方案,研发也要正确实现这个对接方案,会带来一定的额外工作量;此外,如果这个问题处理不好,很容易导致同一个用户在应用上存在多个账号的情况,为用户在平台上的操作带来了困扰。一旦第三方登录出现问题,比如出现服务宕机,或者停止提供登录服务,将会对应用的后续发展造成一定的风险。

四. 第三方登录的实现方式

目前第三方登录的实现方式一般来讲有两种:

纯登录登录+账号绑定

下面来看看这两种实现方式的细节:

1. 纯登录方式

(1)实现策略

使用第三方账号直接登录,即可拥有完整的同本地注册用户相同的待遇。

(2)优势

简单、快捷,用户第一次只需要登录第三方平台并将登录许可授权给应用即可,只要成功,后续就能像应用注册用户一样使用应用内所有服务。

(3)劣势

账号体系在别人手里,一旦第三方登录出现问题,会面临用户及用户数据丢失的风险,给应用的可持续发展带来一定的隐患,只是,考虑到目前提供第三方登录的平台的实力,这种隐患的发生是一个小概率事件。

(4)适用场景

如果你所开发的应用定位与分享、评论、社交,并不涉及必须进行创建应用账号的复杂功能,是比较轻量级的应用,那么你可以选择放弃自主的应用账号体系。比如今日头条、一点资讯等资讯类应用,还有网易云音乐等音乐类应用。

2. 登录+绑定方式

使用第三方登录后,要求绑定应用内账户(如果用户有,则直接绑定,否则需要走应用内的账号注册流程)。

这种实现方式总体上来讲,对应用和用户都是有一定好处的。

对应用来讲:

可以将用户信息牢牢抓在自己手里,防止被第三方拒绝提供服务后丢失本应用积累的用户;可以拿到更多用户的联系信息,比如邮箱、手机号码等,可以为后续的持续营销打下基础;可以避免一个用户多个账号同时存在的情况发生。

对用户来讲:主要是可以防止第三方登录关闭登录服务之后,无法找到自己在应用内的信息的风险。

至于具体的绑定方式,有两种常规的做法:立即绑定和延时绑定。接下来笔者将分别聊聊。

1)实现方式

使用第三方登录后立即需要绑定应用内账号。

2)优势

使得应用内的账号体系比较规整,避免同一个用户产生不同的账号,也进一步避免了同一个用户不同账号之间的数据合并工作。

3)劣势

这种方式给用户的体验不太好,尤其是用户没有本地账号的时候,真的很让人讨厌啊,不但么有减轻用户的注册成本,反而增加了,给用户的感觉是还不如直接注册,多此一举。

4)适用场景

对于店大的应用,你完全可以这么干,比如京东、唯品会这种级别的,因为你对用户的吸引力足够,他为了获得应用的服务,能够忍受这样的额外麻烦。

但对于刚起步的应用,拉新是比较重要的任务和业绩指标,这么干则有一定的风险,因为这样的用户体验是非常糟糕的,用户很可能因为这个设计而骂娘,然后弃你而去。

(2)登录+延时绑定账号

1)实现策略

将第三方登录和账号绑定进行解耦,用户在第三方登录后会获得部分本地注册用户的权限,但在一些关键点上卡住,引导用户绑定一个本地账号,这种做法在用户的便捷性和应用的安全性上取得了一个最好的平衡。

2)优势

降低注册成本,迅速将第三方登录带来的流量留在应用内,提高应用的注册转化率;给用户的体验更贴近于用户的期望(因为登录之后再登录用户很难理解的),第三方登录后可以使用应用了,哪怕是部分功能。

3)劣势

会造成一个用户在绑定应用内账号之前会拥有多个的个人账户:一来给用户的使用造成一定的困扰,二来会因为后续的账号合并带来一定的产品和研发工作量。

4)适用场景

比较适合于刚起步阶段,同时仅仅第三方登录满足不了全部功能需要的应用,比如电商或者O2O类型的应用,因为这样的应用一般会需要用户的手机号,而这个信息第三方登录是提供不了的。

结论

最后结论就是应用账号登录与第三方登录均有利弊,无论何种选择,力求尊重用户,为用户带来方便这个大方向总是不错的。至于具体选择,则要结合自己产品的形态、定位、风格以及愿景来进行选择,不同场景使用不同的实现方式,具体问题具体分析,任何试图用一个方子处理所有问题的企图都是有风险的。

二、请求code (GET请求)

注:请求code仅限于PC端。移动端(APP)由于java无法控制用户手机 拉起(用户手机中)微信应用。所以移动端code由Android和iOS请求、做回调获取code,然后作为参数传给java后台!(仅个人理解,如有不对的地方。望指正、并忽略)

接口地址:https://open.weixin.qq.com/connect/qrconnect?appid=wx4530e35e8a9fc5cd&redirect_uri=http://www.mogujie.com/oauth/callback/weixin/mogujie?referer_key=5E6BA887B6F2988918AD730D730D8D69&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect

(点击链接:可拉起蘑菇街网站‘微信二维码‘登录页面)

一、接下来就借助这个链接中的几个参数,做详细解释:

appid:是在微信开方平台申请的‘应用唯一标识,在微信开放平台提交应用审核通过后获得‘;

redirect_uri:是在微信开方平台申请时填写‘返回code的回调地址‘;

关于redirect_uri回调地址后面的referer_key参数说明:

这个参数可以在后台拼接code请求地址时:加上一个参数,对这个参数生成一个时间戳或uuid、随机数(存入session)。然后拼接到redirect_uri回调地址的后面,这样当你写回调方法的时候可以获取下你在请求code时生成的参数。然后(和session的参数)做下校验用于保持请求和回调的状态,防止跨站请求伪造攻击。

**state参数和referer_key是一样的作用**

response_type:是需要返回的类型,固定填code;

scope:为授权作用域,有两种‘snsapi_base‘和‘snsapi_userinfo‘

关于网页授权的两种scope的区别说明
1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)             - - 静默授权
2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。  - - 手动授权

state:生成一个时间戳或uuid、随机数用于保持请求和回调的状态,授权请求后原样带回给第三方(此参数也可以忽略不传);

二、微信官方对这几个参数的解释:

参数 是否必须 说明
appid 应用唯一标识
redirect_uri 请使用urlEncode对链接进行处理
response_type 填code
scope 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即
state 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验

三、请求code代码

/**微信请求地址 */
//获取code 接口地址 Get
public final static String WEB_CODE_URL = "https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";

//微信回调地址(获取code)
public final static String REDIRECT_URI = "http://服务器域名:端口号(如为80,可忽略端口号)/*****/weixin/*****";

/**
 * 拼接获取code的:接口地址
 * @param state 状态码
 * @return
 */
public static String getCodeURL(String state) {
        return WEB_CODE_URL.replace("APPID",APPID).replace("REDIRECT_URI",REDIRECT_URI).replace("SCOPE",SCOPE).replace("STATE",state);
}

四、回调方法:

controller层:

@RestController
@RequestMapping("/*****")
public class WXController {

        @Autowired
        private WXService weXService;

        @RequestMapping(value = "/weixin/*****")
        public JsonResult  WXLogin(HttpServletRequest request) {
                return weXService.WXLogin(request);
        }
}

service层:

public interface WXService {
    JsonResult WXLogin(HttpServletRequest request);
}

serviceImpl层:

@Service
public class WXServiceImpl {

    @Override
    public JsonResult WXLogin(HttpServletRequest request) {
        //创建一个统一返回对象
        JsonResult jsonResult = new JsonResult();
        /**
         *微信请求回调格式:
         *  允许授权:
         *         redirect_uri?code=CODE&state=STATE
         *  禁止授权:
         *         redirect_uri?state=STATE
         */
        //获取回调地址中的参数code
        String code = request.getParameter("code");
        //获取回调地址中的参数state
        String state = request.getParameter("state");
        //从session中取出state状态码
        Object sessionState = request.getSession().getAttribute("state");
        //校验回调中的state和session中的sessionState是否一致(防止:跨站请求伪造攻击)
        if (sessionState.toString().equals(state)) {
            //校验回调中的code,是否为空
            if (ObjectUtil.isNotEmpty(code)) {
                //根据code向微信服务器发送请求,获取返回参数
                AccessToken accessToken = WeChatUtils.getAccessToken(code);
                //判断微信服务器返回的access_token是否为空
                if (ObjectUtil.isNotEmpty(accessToken.getAccess_token())) {
                    //根据access_token和openid向微信服务器发送请求,获取微信用户信息
                    WeChatUser weChatUserInfo = WeChatUtils.getWeChatUserInfo(accessToken.getAccess_token(), accessToken.getOpenid());
                    //根据返回的openid是否为空,判断‘微信用户信息‘是否成功获取
                    if (ObjectUtil.isNotEmpty(weChatUserInfo.getOpenid())) {
                         /*
                          * 在此处编写具体业务的逻辑!!!
                          *
                          * 在此处编写具体业务的逻辑!!!
                          *
                          * 在此处编写具体业务的逻辑!!!
                          */      
                        }
                    } else {
                        System.out.println("微信用户信息获取失败:错误编码 >> "+weChatUserInfo.getErrcode()+"。错误信息 >> "+weChatUserInfo.getErrmsg());
                        jsonResult.setStatus(2);
                        jsonResult.setData("微信用户信息获取失败");
                    }
                } else {
                    System.out.println("微信授权异常:错误编码 >> "+accessToken.getErrcode()+"。错误信息 >> "+accessToken.getErrmsg());
                    jsonResult.setStatus(2);
                    jsonResult.setMsg("微信授权异常");
                }
            } else {
                jsonResult.setMsg("用户未授权");
                jsonResult.setStatus(2);
            }
        } else {
            jsonResult.setMsg("恶意请求");
            jsonResult.setStatus(2);
        }
        return jsonResult;
    }
}

五、请求code完成,总结需要注意的点:

1.appid、redirect_uri、scope是必传的,缺一不可!

***********************************************

***********************************************

***********************************************

2.在上面请求code中所用到的参数,appid、redirect_uri是需要在微信开放平台上申请的。(换言之,就是这两个参数是要公司提供的)

三、根据code,获取access_token(GET请求)

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

一、接下来就借助这个链接中的几个参数,做详细解释:

appid:同上;

secret:同上;

code:用户授权后,微信服务器返回临时凭证,用于换取access_token;(五分钟有效期)

grant_type:在获取access_token时,这是一个固定值的参数authorization_code;

二、微信官方对这几个参数的解释:

参数 是否必须 说明
appid 应用唯一标识,在微信开放平台提交应用审核通过后获得
secret 应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
code 填写第一步获取的code参数
grant_type 填authorization_code

三、请求access_token代码

//获取access_token 接口地址   Get
public final static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";

/**
 * 获取授权登录access_token
 * @param code 临时授权凭证
 * @return
 */
public static AccessToken getAccessToken(String code) {
        //拼接获取access_token的请求地址
        String accessTokenUrl  = ACCESS_TOKEN_URL.replace("APPID", APPID).replace("SECRET", APPSECRET).replace("CODE", code);

        //发送请求,获取返回结果
        JSONObject jsonObject = HttpsUtils.sendRequest(accessTokenUrl, "GET", null);

        //获取返回的参数,并且封装成AccessToken对象
        AccessToken accessToken = new AccessToken();
        if (jsonObject.getString("access_token") != null) {
            /**
             *  官方返回格式:
             * "access_token":"ACCESS_TOKEN",
             * "expires_in":7200,
             * "refresh_token":"REFRESH_TOKEN",
             * "openid":"OPENID",
             * "scope":"SCOPE",
             * "unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"
             */
            accessToken.setAccess_token(jsonObject.getString("access_token"));
            accessToken.setExpires_in(jsonObject.getString("expires_in"));
            accessToken.setRefresh_token(jsonObject.getString("refresh_token"));
            accessToken.setOpenid(jsonObject.getString("openid"));
            accessToken.setScope(jsonObject.getString("scope"));
            //UnionID机制
            accessToken.setUnionid(jsonObject.getString("unionid"));
        } else {
            /**
             * 错误返回样例:
             * "errcode":40029,
             * "errmsg":"invalid code"
             */
            accessToken.setErrcode(jsonObject.getString("errcode"));
            accessToken.setErrmsg(jsonObject.getString("errmsg"));
        }
        return accessToken;
}

四、根据access_token,获取用户信息(GET请求)

接口地址:https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

一、接下来就借助这个链接中的几个参数,做详细解释:

access_token:根据临时凭证code,获取到的用户有效凭证token,(有效期2小时);

openid:普通用户的标识,对当前开发者帐号(也就是应用、网站)唯一。

二、微信官方对这几个参数的解释:

参数 是否必须 说明
access_token 调用凭证
openid 普通用户的标识,对当前开发者帐号唯一

三、获取用户个人信息的代码

//获取userinfo 接口地址   Get
public final static String WECHAT_USERINFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";

/**
 * 获取用户信息
 * @param accessToken
 * @param openid
 * @return
 */
public static WeChatUser getWeChatUserInfo(String accessToken,String openid) {
        //拼接获取userinfo的请求地址
        String userinfoUrl = WECHAT_USERINFO_URL.replace("ACCESS_TOKEN",accessToken).replace("OPENID",openid);

        //发送请求,获取返回结果
        JSONObject jsonObject = HttpsUtils.sendRequest(userinfoUrl, "GET", null);

        //获取返回的参数,并且封装成WeChatUser对象
        WeChatUser weChatUser = new WeChatUser();
        if (jsonObject.getString("openid") != null) {
            /**
             * 官方返回格式:
             * {
             * "openid":"OPENID",
             * "nickname":"NICKNAME",
             * "sex":1,
             * "province":"PROVINCE",
             * "city":"CITY",
             * "country":"COUNTRY",
             * "headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
             * "privilege":[PRIVILEGE1","PRIVILEGE2"],
             * "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
             * }
             */

            weChatUser.setOpenid(jsonObject.getString("openid"));
            weChatUser.setNickname(jsonObject.getString("nickname"));
            weChatUser.setSex(jsonObject.getString("sex"));
            weChatUser.setProvince(jsonObject.getString("province"));
            weChatUser.setCity(jsonObject.getString("city"));
            weChatUser.setCountry(jsonObject.getString("country"));
            weChatUser.setHeadimgurl(jsonObject.getString("headimgurl"));
            weChatUser.setPrivilege(jsonObject.getString("privilege"));
            weChatUser.setUnionid(jsonObject.getString("unionid"));
        } else {
            /**
             * 错误返回样例:
             * "errcode":40003,
             * "errmsg":"invalid openid"
             */
            weChatUser.setErrcode(jsonObject.getString("errcode"));
            weChatUser.setErrmsg(jsonObject.getString("errmsg"));
        }
        return weChatUser;
}

五、结尾

在本篇博客中所用的到所有工具类均在下面链接中可以找到,后续有时间会对代码进行更新和加入其它的第三方登录!

在下面链接中有在项目中的实际案例!可供参考...

项目源码:https://gitee.com/qcxdld/open_logon

原文地址:https://www.cnblogs.com/2019gdiceboy/p/11384312.html

时间: 2024-11-03 16:13:19

微信第三方登录 -- (PC端+移动端)的相关文章

小程序-文章:微信第三方登录(静默授权和非静默授权)

ylbtech-小程序-文章:微信第三方登录(静默授权和非静默授权) 1.返回顶部 1. 用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑. 微信的授权登录在日常应用中应用的非常广泛,越来越多的平台支持用户使用微信进行授权第三方登录 使用微信授权登录有哪些优势/好处: 1.用户量足够大,基本所有用户都会有微信,登录起来比较方便快捷: 2.微信作为一个开放平台,为众多公众号/服务开放了许多服务接口,让公众号能够为自己的用户提供更加个性.更加优质

【第三方登录】之微信第三方登录

网站微信第三方登录里面,用的是 微信开放平台  中申请的 APPID 和 APPSECRET.回调地址下的代码如下: public partial class WeiXinLogin : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { WeiXinLoginAPI(); } public const string APPID = ""; public const string APP

微信公众平台开发(31)微信第三方登录接口

原文: http://www.cnblogs.com/imaker/p/5491433.html 第一步:获取AppID AppSecret(不做解释,自己去微信公众平台申请) 第二步:生成扫描二维码,获取code https://open.weixin.qq.com/connect/qrconnect?appid=AppID&redirect_uri=http://www.baidu.com&response_type=code&scope=snsapi_login&st

微信第三方登录接口

第一步:获取AppID AppSecret(不做解释,自己去微信公众平台申请) 第二步:生成扫描二维码,获取code https://open.weixin.qq.com/connect/qrconnect?appid=AppID&redirect_uri=http://www.baidu.com&response_type=code&scope=snsapi_login&state=2014#wechat_redirect 第三步:通过code获取access_token

微信公众号与APP微信第三方登录账号打通

一个项目同时开发了APP和微信服务号,需要做到APP和微信服务号的账号互通同步,也就是说一个账号在2个地方都可以用,当然这个前提是保证你公司自己的服务器的数据库用的是同一套. 为保证用户数据的唯一性,打通app与公众号的数据,需要做如下工作: 1.申请appid, 在-登录微信开放平台--申请账号(如果没有,就去注册,不能使用公众号登录或注册)--开发者资质认证(账号中心,认证时需提交很多资料:等待认证结果)--认证通过之后,创建应用(管理中心,创建你要开发的app,等待审核):以上是app需要

对于QQ、微博、微信第三方登录的思考

今天聊聊注册.登录环节中很常见的第三方登录,如QQ.微信.支付宝.新浪微博等.虽然这些产品的开放平台都提供了标准的接入文档,但是在接入时还有些问题需要想清楚. 1 第三方登录目的 第三方登录的目的很简单,就是利用用户在其他平台上频繁使用的账号,来快速登录你的产品,达到不注册就登录的目的. 2 第三方登录好处 第三方登录的好处,显而易见. 不需要注册账号,直接使用已有的QQ号.微信等登录.减少了注册环节,减少了因为注册而流失的用户. 可以直接获取用户昵称.头像等信息,省去再次填写昵称.上传头像的麻

Android Learning:微信第三方登录

这两天,解决了微信第三方授权登录的问题,作为一个新手,想想也是一把辛酸泪.我想着,就把我的遇到的坑给大家分享一下,避免新手遇到我这样的问题能够顺利避开. 步骤一 微信开发者平台 我开始的解决思路是,去微信开发者平台看API文档. 这个API文档的主要意思呢,有三点: 1.你得下载这几样东西(下载链接),一个是他的范例代码,一个是他的签名生成工具. 2.如果你自己的APP想要微信第三方授权,你得去申请一个APPID,这个APPID呢,就是微信给咱们APP分配的一个代号.当然微信不是免费给你服务,为

微信第三方登录与静默授权和非静默授权

微信的授权登录在日常应用中应用的非常广泛,最多就是第三方登录 微信登录分为两类:授权登录(非静默授权)与静默授权 授权登录:需要用户确认登录,这样可以通过用户的个人确认,获取用户全面的信息,无论是否关注相关微信公众号等都可以获取. 静默授权不需要用户确认,只需要用户访问某个网页,属于嵌套在普通网页里的授权形式,但是只能获取到用户的唯一标示openid,无法获取用户的个人信息,对于用户的简单认证还是很有用的.

PHP实现微信第三方登录的方法

本文实例讲述了PHP版微信第三方实现一键登录及获取用户信息的方法.分享给大家供大家参考,具体如下: 注意,要使用微信在第三方网页登录是需要"服务号"才可以哦,所以必须到官方申请 一开始你需要进入微信公众平台开启开发模式,并且填写oauth2的回调地址,地址填写你项目的域名就可以了.比如:www.baidu.com或zhidao.baidu.com.如果你的项目在二级域名就写二级域名 前端url授权地址,在url中填写appid与你项目中方法中的oauth的地址,具体在下面的代码中可以看