精华内容
下载资源
问答
  • 缺少第三方登录
    千次阅读
    2017-06-30 11:17:45

    使用友盟第三方登录QQ,点击登录无响应,不走回调方法。

    解决方法是查看URL Schemes设置是否正确,友盟官网上说是appid,其实并不是苹果官网的appid,而是腾讯开发者平台的key

    更多相关内容
  • 公众平台第三方平台是为了让公众号或小程序运营者,在面向垂直行业需求时,可以一键授权给第三方平台(并且可以同时授权给多家第三方),通过第三方平台来完成业务,开放给所有通过开发者资质认证后的开发者使用。...

    一、概述

    公众平台第三方平台是为了让公众号或小程序运营者,在面向垂直行业需求时,可以一键授权给第三方平台(并且可以同时授权给多家第三方),通过第三方平台来完成业务,开放给所有通过开发者资质认证后的开发者使用。

    从具体的业务场景上说,第三方平台包括以下场景:

    1、提供行业解决方案,如针对电商行业的解决方案,或针对旅游行业的解决方案等

    2、对公众平台功能的优化,如专门优化图文消息视觉样式和排版的工具,或专门定制的CRM用户管理功能,或功能强大的客服系统

    在技术上,第三方平台是通过获得公众号或小程序的接口能力的授权,然后代公众平台帐号调用各业务接口来实现业务的,因此,第三方平台在调用各接口时,必须遵循公众平台运营规范,详见:《微信公众平台运营规范》。

    为了便于管理,也为了帮助公众平台运营者快速理解和授权自己的接口和功能权限,微信开放平台将各种接口权限进行了专门的组织,请见:【第三方平台权限集介绍页】

    二、第三方平台的申请和上线流程

    开发者在接入第三方平台开发时,申请和上线流程如下:

    1、创建第三方平台

    在微信开放平台中,填写第三方平台的基本信息、需要的权限和相关参数(具体参数说明请见填写流程中说明)后,即可创建第三方平台。对于一些所需填写的信息说明,请见:【第三方平台申请资料说明】

    2、开发者自行开发和测试授权

    创建后,第三方开发者可以根据1中所填写的测试白名单中的公众号,自行进行公众号的开发和授权流程的测试(不能专门新建一个第三方平台用于测试)。同时还需要针对专用测试公众号的消息推送进行适当的处理,具体详见《全网发布接入检测》,必须预先按照全网发布接入检测说明进行准备后,才可以申请全网发布。

    3、申请全网发布并上线

    第三方开发者在使用1中所填写的测试白名单中的公众号自行测试完成后,可以申请全网发布,并等待审核通过。审核通过后,第三方平台可以面向所有符合要求的公众号进行登录授权,换句话说,第三方开发者的第三方平台业务就可以上线了。

    4、发布后修改和覆盖现网

    如果第三方平台发生了业务变更,需要修改第三方平台的资料,则需要先对第三方平台进行修改,但此时修改只会对测试公众号生效,开发者还需要提交“覆盖现网全网发布”后,才可令修改面向公众发布。请注意,修改过程中,现网正在使用的公众号是完全不受影响,可以正常使用的。

    三、公众帐号授权给第三方平台的授权流程技术说明

    请根据本文档目录中的《授权流程技术指引文档》,来了解如何完成授权流程

    四、第三方平台授权后如何帮助旗下公众平台帐号实现业务

    请根据本文档目录中的“代公众号实现业务”文件夹中的相关文档,来了解如何帮助旗下公众号调用接口,实现业务。也可根据本文档目录中的“代小程序实现业务”文件夹中的相关文档,来了解如何帮助旗下小程序帐号调用接口,实现业务。

    五、FAQ

    1、为什么创建第三方平台需要开发者资质认证?

    第三方平台是为了满足企业、媒体、商家等公众帐号运营者的垂直行业需求,因此需要比较强的开发能力,也需要安全的开发者资质,因此,开发者创建第三方平台之前,需要先通过开发者资质认证。

    2、为什么第三方平台需要进行测试和全网发布?

    开发者在创建完第三方平台之后,并不是立刻就需要将第三方平台给所有公众平台帐号使用,如果是给公众号提供服务,则必须预先自行通过测试公众号(测试公众号在创建第三方平台时可以设置)来完成第三方平台的测试,测试通过后,再提交全网发布,以确保普通的公众号运营者使用的公众号第三方平台都是基本可用的。

    3、如何做到无需公众平台帐号设置繁琐参数?

    只要公众平台帐号确认授权托管给了第三方平台,第三方平台方就可以代替公众平台帐号进行消息回复、网页授权等相应业务能力,第三方平台方代替完成业务过程中,是依靠第三方平台自身的开发参数设置来完成的,不涉及自身的设置。

    4、订阅号、服务号、企业号的授权流程有什么区别?

    订阅号、服务号可以进行登录授权的,都可以被公众号第三方平台开发者服务。但是需要注意,第三方平台在代替公众号完成业务时,需要公众号自身已有相关权限,换句话说,订阅号在缺少某些接口权限的情况下,第三方平台依旧不能代替其实现。企业号由于接口权限与服务号、订阅号不同,暂不完全支持登录授权。

    5、授权后,用第三方平台还是公众号的AppID来开发?

    授权之后,除第三方平台代公众号发起网页授权的过程中,需要用到公众号AppID之外,其他接口的调用,一般是根据第三方平台方的开发凭据(授权公众号的令牌)来完成的,当然第三方平台方在获得开发凭据时,需要公众号的AppID等信息。

    6、创建第三方平台时需要的参数中,授权回调域名和网页回调域名有什么区别?

    授权回调域名和网页回调域名是创建第三方平台时必须的2个参数。前者用于公众号运营者授权托管给第三方平台方的流程中,后者用于公众号授权给第三方平台之后,第三方平台代替公众号进行网页授权的流程中。

    7、为什么要进行消息加密

    为了确保第三方平台方所托管的众多公众号的业务安全,第三方平台方的消息收发过程中,需要进行消息加密,具体消息加密细节请见【消息加解密说明】

    8、为什么要进行全网发布接入检测?

    为了确保经过全网发布的第三方平台都是可用的,微信服务器会自动对提交全网发布的第三方平台进行基础消息逻辑检测,以确保第三方平台稳定。具体检测过程说明请见 【全网发布接入检测说明】

    尾声

    以上文字均来源于微信开放平台官方文档,目的是让大家对第三方平台有一个较为明确的概念,这里我想用一句话概括:第三方平台是代理微信(公众号和小程序等)处理相关业务的平台

    展开全文
  • python实现QQ第三方登录

    千次阅读 2018-11-23 23:35:59
    QQ登录开发文档连接 http://wiki.connect.qq.com/准备工作_oauth2-0 腾讯QQ互联平台没有python SDK,我们使用封装好的SDK包 安装:pip install QQLoginTool 导入:from QQLoginTool.QQtool import OAuthQQ OAuth...

    应用接入前,首先需进行申请,获得对应的appid与appkey,以保证后续流程中可正确对网站与用户进行验证与授权。http://wiki.connect.qq.com/__trashed-2
    QQ登录开发文档连接 http://wiki.connect.qq.com/准备工作_oauth2-0
    腾讯QQ互联平台没有python SDK,我们使用封装好的SDK包
    安装:pip install QQLoginTool
    导入:from QQLoginTool.QQtool import OAuthQQ

    OAuthQQ类中的方法:
    __init__(self, client_id=None, client_secret=None, redirect_uri=None, state=None):
    
    • client_id : 申请QQ登录成功后,分配给应用的appid。
    • client_secret:申请QQ登录成功后,分配给网站的appkey。
    • redirect_uri:成功授权后的回调地址,必须是注册appid时填写的主域名下的地址,建议设置为网站首页或网站的用户中心。注意需要将url进行URLEncode。
    • state:client端的状态值。用于第三方应用防止CSRF攻击,成功授权后回调时会原样带回。请务必严格按照流程检查用户与state参数状态的绑定。
    get_qq_url(self)   # 获取QQ登录网页网址
    get_access_token(self, code)  # 获取access_token值
    get_open_id(self, access_token)  # 获取open_id值
    

    下面以Django为例实现QQ第三方登录

    过程:

    获取QQ登录网页网址
    接口设计:
    请求方式:GET /?state=xxx
    请求参数:

    参数名类型是否必须说明
    statestr登录成功后的跳转页面路径

    返回数据:JSON

    {
        login_url": "https://graph.qq.com/oauth2.0/show?which=Login&display=pc&response_type=code&client_id=**&redirect_uri=**&state=**&scope=**"
    }
    
    返回值说明
    login_urlqq登录网址

    代码实现:

    
    from QQLoginTool.QQtool import OAuthQQ
    from django.conf import settings
    from rest_framework.views import APIView
    
    ...
    
    # 获取login_url
    class OauthQQLogin(APIView):
    
        def get(self, request):
    
            # 获取前端传入的参数
            state = request.query_params.get('next', None)
            # 判断是否有,如果没有后端创建一个
            if not state:
                state = '/'
            # 实例化对象
            oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI, state=state)
            # 获取login_url
            login_url = oauth.get_qq_url()
            # 返回login_url
            return Response({'login_url': login_url})
    

    获取openid

    在QQ将用户重定向到此网页的时候,重定向的网址会携带QQ提供的code参数,用于获取用户信息使用,我们需要将这个code参数发送给后端,在后端中使用code参数向QQ请求用户的身份信息

        /oauth_callback.html?code=****&state=%2F
    

    oauth_callback回调页,用于扫码后接受Authorization Code
    通过Authorization Code获取Access Token
    然后通过Access Token获取openid

    接口设计:
    请求方式:GET /?code=xxx
    请求参数:

    参数名类型是否必须说明
    codestrqq返回的授权凭证code

    返回数据:JSON

    {
        "openid": xxxx 
    }
    
    返回值说明
    openid用户的ID,与QQ号码一一对应。

    代码实现:

    from QQLoginTool.QQtool import OAuthQQ
    from django.conf import settings
    from itsdangerous import TimedJSONWebSignatureSerializer as TJS
    from rest_framework.views import APIView
    
    ...
    
    # 获取openid 
    class OauthQQToken(APIView):
        def get(self, request):
            # 获取前端传入的code
            code = request.query_params.get('code', None)
            # 判断是否有,如果没有直接return
            if not code:
    	    return Response({'message': '缺少code'})
    
    	oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,redirect_uri=settings.QQ_REDIRECT_URI)
            try:
    	    # 使用code向QQ服务器请求access_token
    	    access_token = oauth.get_access_token(code)
    	    # 使用access_token获取openid
    	    openid = oauth.get_open_id(access_token)
            except:
    	    return Response({'message': 'QQ服务异常'})
           
       	...
    

    下面可以根据具体需求,进一步向后扩展…

    以上内容仅供参考 -_- …为作者边学习,边摘抄和总计的内容

    展开全文
  • 根据需求,需要拥有第三方微信登录功能,并获取到用户信息。 网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。 二、前期准备工作 1、注册邮箱账号。 2、根据邮箱账号注册微信开放平台账号,...

    一、概述

    根据需求,需要拥有第三方微信登录功能,并获取到用户信息。
    网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。

    二、前期准备工作

    1、注册邮箱账号。

    2、根据邮箱账号注册微信开放平台账号,完善开发者资料。

    3、申请开发者资质认证、填写相关资料、填写发票、支付认证金额。提交并等待认证结果

    1)申请开发者资质认证
    
    2)选定类型
    
    3)填写“认证资料”
    
    4)填写“管理员信息”
    
    5)上传“企业基本信息”材料:
    
    6)进入填写发票及支付费用
    

    4、认证成功后,创建网站应用,填写基本信息、下载网站信息登记表填写并上传扫描件、填写授权回调域等。提交审核等待结果。

    1)创建网站应用
    
    2)创建移动应用
    

    5、认证成功后,创建移动应用,至少选择安卓、IOS、WP8其中一种平台

    6、创建应用成功后,申请微信登陆,等待审核结果,待审核通过后,可进行微信登陆的开发。

    注:创建应用和开发者资质认证可同时进行
    在这里插入图片描述
    准备工作大致流程图

    三、开发流程

    1)第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;

    2)通过code参数加上AppID和AppSecret等,通过API换取access_token;

    3)通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。
    在这里插入图片描述

    四、具体实现步骤

    1、准备工作

    1)添加依赖

    <!-- 添加httpclient支持 -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>
    

    2)配置文件

    ## 微信开放平台
    wechat:
     open:
       # APPID
       appid: ******
       # APPSECRET
       appsecret: ******
       # 回调地址
       redirect_uri: http://de43f7.39nat.com
    

    3)实体类

    /**
    *
    * @author: xxm
    * 功能描述: access_token封装基础类
    * @date: 2021/2/2 10:41
    */
    @Data
    public class Token {
     private String openid; //授权用户唯一标识
     private String accessToken; //接口调用凭证
     private Integer ExpiresIn; //access_token接口调用凭证超时时间,单位(秒)
    }
    
    /**
    *
    * @author: xxm
    * 功能描述: 微信与网站绑定关系表
    * @date: 2021/2/1 17:08
    */
    @Data
    @Table(name = "UserWeChat")
    @NameStyle(Style.normal)
    public class UserWeChat implements Serializable {
       private static final long serialVersionUID = 8997358443007506192L;
       @Id
       @GeneratedValue(generator = "JDBC")
       private Integer id;
       //用户id
       private Integer userId;
       //微信OpenId
       private String openId;
       //昵称
       private String nickName;
    }
    
    /**
    *
    * @author: xxm
    * 功能描述: access_token封装基础类
    * @date: 2021/2/2 10:41
    */
    @Data
    public class Token {
     private String openid; //授权用户唯一标识
     private String accessToken; //接口调用凭证
     private Integer ExpiresIn; //access_token接口调用凭证超时时间,单位(秒)
    }
    

    4)微信工具类

    /**
    *
    * @author: xxm
    * 功能描述: 微信登录相关接口工具类
    * @date: 2021/2/23 16:14
    * @param: 
    * @return: 
    */
    public class WeChatCommonUtil {
    
       private static Logger log = LoggerFactory.getLogger(WeChatCommonUtil.class);
       /**
        * @author: xxm
        * 功能描述: urlEncodeUTF8工具类
        * (用于将扫描二维码后重定向的资源url进行编码)
        * @date: 2021/2/22 15:55
        * @param:
        * @return:
        */
       public static String urlEncodeUTF8(String source) {
       	String result = source;
       	try {
       		result = java.net.URLEncoder.encode(source, "utf-8");
       	} catch (UnsupportedEncodingException e) {
       		e.printStackTrace();
       	}
       	return result;
       }
       /**
        *
        * @author: xxm
        * 功能描述: 获取openid等信息的方法
        * @date: 2021/2/22 17:52
        * @param: 
        * @return: 
        */
       public static Token getTokenWithOpenid(String appid, String appsecret, String code) {
       	String findAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
       	Token token = null;
       	// 发起GET请求获取凭证
       	String requestUrl = findAccessTokenUrl.replace("APPID", appid).replace("SECRET", appsecret).replace("CODE", code);
       	JSONObject jsonObject = JSONObject.fromObject(httpsRequest(requestUrl, "GET", null));
    
       	if (null != jsonObject) {
       		try {
       			token = new Token();
       			token.setOpenid(jsonObject.getString("openid"));
       			token.setAccessToken(jsonObject.getString("access_token"));
       			token.setExpiresIn(jsonObject.getInt("expires_in"));
       		} catch (JSONException e) {
       			token = null;
       			// 获取token失败
       			log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
       		}
       	}
       	return token;
       }
       /**
        *
        * @author: xxm
        * 功能描述: 根据openid获取用户信息的方法
        * @date: 2021/2/22 17:52
        * @param: 
        * @return: 
        */
       public static WechatUserInfo getUserinfo(String access_token, String openid) {
       	WechatUserInfo wxuse = new WechatUserInfo();
       	String findUseinfo = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
       	String requestUrl = findUseinfo.replace("ACCESS_TOKEN", access_token).replace("OPENID", openid);
       	JSONObject jsonObject = JSONObject.fromObject(httpsRequest(requestUrl, "GET", null));
       	if (null != jsonObject) {
       		try {
       			wxuse.setNickname(jsonObject.getString("nickname"));
       			wxuse.setHeadimgurl(jsonObject.getString("headimgurl"));
       			wxuse.setUnionid(jsonObject.getString("unionid"));
       			wxuse.setOpenid(jsonObject.getString("openid"));
       		} catch (JSONException e) {
       			e.printStackTrace();
       		}
       	}
       	return wxuse;
       }
       /**
        * 发送https请求
        *
        * @param requestUrl 请求地址
        * @param requestMethod 请求方式(GET、POST)
        * @param outputStr 提交的数据
        * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
        * 返回微信服务器响应的信息
        */
       public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
       	try {
       		// 创建SSLContext对象,并使用我们指定的信任管理器初始化
       		TrustManager[] tm = { new MyX509TrustManager() };
       		SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
       		sslContext.init(null, tm, new java.security.SecureRandom());
       		// 从上述SSLContext对象中得到SSLSocketFactory对象
       		SSLSocketFactory ssf = sslContext.getSocketFactory();
       		URL url = new URL(requestUrl);
       		HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
       		conn.setSSLSocketFactory(ssf);
       		conn.setDoOutput(true);
       		conn.setDoInput(true);
       		conn.setUseCaches(false);
       		// 设置请求方式(GET/POST)
       		conn.setRequestMethod(requestMethod);
       		conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
       		// 当outputStr不为null时向输出流写数据
       		if (null != outputStr) {
       			OutputStream outputStream = conn.getOutputStream();
       			// 注意编码格式
       			outputStream.write(outputStr.getBytes("UTF-8"));
       			outputStream.close();
       		}
       		// 从输入流读取返回内容
       		InputStream inputStream = conn.getInputStream();
       		InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
       		BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
       		String str = null;
       		StringBuffer buffer = new StringBuffer();
       		while ((str = bufferedReader.readLine()) != null) {
       			buffer.append(str);
       		}
       		// 释放资源
       		bufferedReader.close();
       		inputStreamReader.close();
       		inputStream.close();
       		conn.disconnect();
       		return buffer.toString();
       	} catch (ConnectException ce) {
       		log.error("连接超时:{}", ce);
       	} catch (Exception e) {
       		log.error("https请求异常:{}", e);
       	}
       	return null;
       }
       
    }
    
    /**
    * @author: xxm
    * @description:信任管理器
    * @date: 2021/2/22 17:41
    */
    public class MyX509TrustManager implements X509TrustManager {
    
       // 检查客户端证书
       @Override
       public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
       }
    
       // 检查服务器端证书
       @Override
       public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
       }
    
       // 返回受信任的X509证书数组
       @Override
       public X509Certificate[] getAcceptedIssuers() {
           return null;
       }
    }
    

    2、请求获取Code

    前提:应用已经获取相应的网页授权作用域(scope=snsapi_login)

    开发:第三方网站引导用户打开链接

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

    参数说明:
    在这里插入图片描述

    注意:若提示“该链接无法访问”,请检查参数是否填写错误,如redirect_uri的域名与审核时填写的授权域名不一致或scope不为snsapi_login。

    /**
        *
        * @author: xxm
        * 功能描述: 跳转至登录授权页面(页面出现二维码)
        * @date: 2021/2/22 17:50
        * @param: 
        * @return: 
        */
       @RequestMapping("/login")
       public String openWeChatLogin() {
           // 防止csrf攻击(跨站请求伪造攻击)
           String state = UUID.randomUUID().toString().replaceAll("-", "");
           String url = "https://open.weixin.qq.com/connect/qrconnect?" +
                   "appid=" +
                   env.getProperty("wechat.open.appid").trim() +
                   "&redirect_uri=" +
                   WeChatCommonUtil.urlEncodeUTF8(env.getProperty("wechat.open.redirect_uri").trim()+"/wechat/weChatLogin_epf") +
                   "&response_type=code" +
                   "&scope=snsapi_login" +
                   // 由后台自动生成
                   "&state=" + state +
                   "#wechat_redirect";
    
           return "redirect:" + url;
       }
    

    3、用户同意授权与否

    用户允许授权后,将会重定向到redirect_uri的网址上,并且带上code和state参数

    redirect_uri?code=CODE&state=STATE

    若用户禁止授权,则不会重定向到我们提供的回调地址中

    成功授权后,将获得Code,通过Code可以获取access_token

    4、获取access_token

    通过上述方法获取的code获取access_token.

    Http Get请求

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

    参数说明:
    在这里插入图片描述

    请求后,

    返回成功的json串为(样例):

    {
    “access_token”:“ACCESS_TOKEN”, // 接口调用凭证
    “expires_in”:7200, // access_token接口调用凭证超时时间,单位(秒)
    “refresh_token”:“REFRESH_TOKEN”, //用户刷新access_token
    “openid”:“OPENID”, //授权用户唯一标识
    “scope”:“SCOPE”, //用户授权的作用域,使用逗号(,)分隔
    “unionid”: “o6_bmasdasdsad6_2sgVt7hMZOPfL” //当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段
    }

    失败返回的样例:

    {“errcode”:40029,“errmsg”:“invalid code”}

    失败可能原因: 暂时不明

    Token tokenWithOpenid = WeChatCommonUtil.getTokenWithOpenid(loginAppid, loginSecrect, code);
    

    5、通过access_token调用接口获取用户个人信息(UnionID机制)

    前提:

    1. access_token有效且未超时;

    2. 微信用户已授权给第三方应用帐号相应接口作用域(scope)。

    Http Get请求:

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

    参数
    在这里插入图片描述

    返回成功的json结果(样例):

    {
    “openid”:“OPENID”, //普通用户的标识,对当前开发者帐号唯一
    “nickname”:“NICKNAME”, //普通用户昵称
    “sex”:1, //普通用户性别,1为男性,2为女性
    “province”:“PROVINCE”, //普通用户个人资料填写的省份
    “city”:“CITY”, //普通用户个人资料填写的城市
    “country”:“COUNTRY”, //国家,如中国为CN
    “headimgurl”: “http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0”, //用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
    “privilege”:[ //用户特权信息,json数组,如微信沃卡用户为(chinaunicom)
    “PRIVILEGE1”,
    “PRIVILEGE2”
    ],
    “unionid”: " o6_bmasdasdsad6_2sgVt7hMZOPfL" //用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的
    }

    失败JSON样例:

    {“errcode”:40003,“errmsg”:“invalid openid”}

    注意:在用户修改微信头像后,旧的微信头像URL将会失效,因此开发者应该自己在获取用户信息后,将头像图片保存下来,避免微信头像URL失效后的异常情况

    最好保存用户unionID信息,以便以后在不同应用中进行用户信息互通。

      //通过access_token调用接口
      WechatUserInfo wxuse = WeChatCommonUtil.getUserinfo(access_token, openid);
    

    6、授权成功后台处理

    获取到access_token,在通过access_token获取到微信用户信息WechatUserInfo,就可以判断微信账号是否已经与网站账号关联 ,如果关联了,则此处可以直接登录跳转到主页,但在此处,我还是用了Spring Security安全框架,所有需要微信登录需要经过Spring Security的url请求进行验证,才可以登录。
    如果微信账号没有关联网站账号,则可以跳转到微信绑定页面,完成微信绑定。

      /**
         *
         * @author: xxm
         * 功能描述: 授权成功后
         * @date: 2021/2/22 17:50
         * @param:
         * @return:
         */
        @ResponseBody
        @RequestMapping("/weChatLogin_epf")
        public ModelAndView weChatLogin_epf(HttpServletRequest request, HttpSession session, RedirectAttributes attribute){
            ModelAndView model = new ModelAndView();
            //获取到code,这个code应该是微信那边定义的
            String code = request.getParameter("code");
            //第三方网站(即我们自己)自定义的参数,可以存储一些重要信息和防伪信息,因为这个接口是完全暴露的,所以必须要有防伪措施,防止恶意请求来搞事
            String state=request.getParameter("state");
            //如果这两个字段都为空值,就可以判定为而已请求
            if(StringUtils.isBlank(code)||StringUtils.isBlank(state)){
                logger.info("非法请求,缺少必要的参数");
                model.setViewName("redirect:/login");
                attribute.addFlashAttribute("errorInfo", "非法请求,缺少必要的参数!");
                attribute.addFlashAttribute("success", false);
                return model;
            }
            logger.info("获取到的code是 :" + code+",state="+state);
            //通过code获取access_token
            String loginAppid = env.getProperty("wechat.open.appid").trim();
            String loginSecrect = env.getProperty("wechat.open.appsecret").trim();
            try {
                Token tokenWithOpenid = WeChatCommonUtil.getTokenWithOpenid(loginAppid, loginSecrect, code);
                if (null != tokenWithOpenid) {
                    String openid = tokenWithOpenid.getOpenid();
                    String access_token = tokenWithOpenid.getAccessToken();
                    //通过access_token调用接口
                    WechatUserInfo wxuse = WeChatCommonUtil.getUserinfo(access_token, openid);
                    logger.info("微信用户信息:" + wxuse);
    
                    UserWeChatDto uwcDto = new UserWeChatDto();
                    uwcDto.setOpenId(openid);
                    List<UserWeChatDto> uwcList = userWeChatClient.getListByParam(uwcDto);
                    if (null != uwcList && uwcList.size()==1) {
                        UserWeChatDto userWeChatDto = uwcList.get(0);
                        //微信账号已经与网站账号关联
                        //根据用户id查询用户
                        SysUser currentUser = userControllerClient.getUserById(userWeChatDto.getUserId());
                        session.setAttribute("username", currentUser.getUsername());
                        // 微信登录需要经过的url请求
                        model.setViewName("redirect:/wechat/weChatLogin");
                        model.addObject("openid",openid);
                        attribute.addFlashAttribute("success", true);
                    } else {
                        //微信账号没有关联网站账号
                        String url = "redirect:/weChatBind";
                        model.setViewName(url);
                        attribute.addFlashAttribute("wechatUserInfo", wxuse);
                        attribute.addFlashAttribute("nickname", wxuse.getNickname());
                        attribute.addFlashAttribute("openid", wxuse.getOpenid());
                    }
    
                } else {
                    logger.error("获取token失败");
                    model.setViewName("redirect:/login");
                    attribute.addFlashAttribute("errorInfo", "获取token失败!");
                    attribute.addFlashAttribute("success", false);
                }
            }catch (Exception e) {
                e.printStackTrace();
                model.setViewName("redirect:/login");
                attribute.addFlashAttribute("errorInfo", "微信授权登录失败!");
                attribute.addFlashAttribute("success", false);
            }finally {
                return model;
            }
        }
    

    7、刷新access_token

    由于access_token有效期(目前为2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新,access_token刷新结果有两种:

    1. 若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间;
    2. 若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token。

    refresh_token拥有较长的有效期(30天),当refresh_token失效的后,需要用户重新授权。

    请求方法:

    获取第一步的code后,请求以下链接进行refresh_token:

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

    参数说明:
    在这里插入图片描述
    成功返回的结果:
    {
    “access_token”:“ACCESS_TOKEN”, //接口调用凭证
    “expires_in”:7200, // access_token接口调用凭证超时时间,单位(秒)
    “refresh_token”:“REFRESH_TOKEN”, //用户刷新access_token
    “openid”:“OPENID”, //授权用户唯一标识
    “scope”:“SCOPE” //用户授权的作用域,使用逗号(,)分隔
    }

    失败样例:

    {“errcode”:40030,“errmsg”:“invalid refresh_token”}

    注意:

    1、Appsecret 是应用接口使用密钥,泄漏后将可能导致应用数据泄漏、应用的用户数据泄漏等高风险后果;存储在客户端,极有可能被恶意窃取(如反编译获取Appsecret);
    2、access_token 为用户授权第三方应用发起接口调用的凭证(相当于用户登录态),存储在客户端,可能出现恶意获取access_token 后导致的用户数据泄漏、用户微信相关接口功能被恶意发起等行为;
    3、refresh_token 为用户授权第三方应用的长效凭证,仅用于刷新access_token,但泄漏后相当于access_token 泄漏,风险同上。

    建议将secret、用户数据(如access_token)放在App云端服务器,由云端中转接口调用请求。

    五、测试结果

    请自己测试

    展开全文
  • (1):如何添加python第三方库(方法一):File ->> Settings... ->> Project Interpreter(2):如何添加python第三方库(方法二):步骤:1、Win键+R ,输入“cmd” 调出命令窗口;2、输入:python -m pip install --...
  • gitlab 之第三方OAuth登录接入(一)

    千次阅读 2020-12-19 21:36:50
    Gitlab 内置了一些第三方接入的OAuth Provider,可以便捷的接入像Google、Github、Facebook等第三方登录。而在公司内部,尤其是中国的公司内部,使用这些登录几乎是扯淡。LDAP是个很好的选择方案,但这里要说的不是...
  • 最近遇到的一个问题,老项目的第三方以iframe嵌入的网页,无法正常登录了。 定位问题,发现: 控制台报错401 (Unauthorized),导致的无法正常登录。是因为我们iframe的问题,产生了跨域,导致我们的cookie无法共享。...
  • 5.加入第三方的activity QQ: android:name="com.tencent.tauth.AuthActivity" android:launchMode="singleTask" android:noHistory="true"> android:name=...
  • qq第三方登陆授权失败出现代码110401是什么情况?遇到这种情况该如何解决?相信很多用户们在操作的时候都出现过类似的情况吧?下面是小编带来的攻略解析,一起来关注下! qq第三方登陆授权失败110401错误码解决办法...
  • 110201:未登陆 110405:登录请求被限制 110404:请求参数缺少appid 110401:请求的应用不存在 110407:应用已经下架 110406:应用没有通过审核
  • 第三方登录不得不说的一个优势:那就是本地注册和第三方注册的选择。虽然这是一个不能称之为问题的问题,其中的心理学不得不说:做为一个app的新用户,你有两个选择:1....2.第三方登录后,随机分配一个id
  • 手机QQ2019V7.9.9官方最新版类型:社交聊天大小:57.6M语言:中文 评分:9.9标签:立即下载qq第三方登陆授权失败110401错误码该怎么解决是大家想要知道的,不少小伙伴们不知道这个解决办法的,想要知道自己该怎么...
  • 我们知道python安装第三方包可以用pip install package 、conda install package 等命令,但实际中总有些不可抗力导致这些命令不能用,这时就需要离线安装第三方包。 离线安装包可以在 https://pypi.org/ ...
  • 1.接入第三方应用 http://faqrobothttp://faqrobot/webchatbot/chat.html?sysNum=1623047917475&sourceId=101&lang=zh_CN/webchatbot/chat.html?sysNum=1623047917475&sourceId=101&lang=zh_CN
  • 原先公众号的登录注册由于session的频繁...我接着以openId为key将用户的登录状态保存到redis数据库中,但是按照之前项目的设计,只有从公众号菜单栏点击进来的链接才能获取到openId,对于非菜单栏的链接,是获取不...
  • 大家都知道 pip 在安装第三方库的时候是十分方便的,在 Windows 平台上,一条命令就可以将依赖关系都搞定: pip install requests 但还是有几个小问题。 1.有时候会提示权限不够。 当初没有留下那个权限不足...
  • 微信的官方文档没有找到完整的说明,以下数据是一个一个授权对比得到,特此备注 return [ '17' => '帐号管理权限', '18' => '开发管理与数据分析权限', '19' => '客服消息管理权限', ...
  • python中第三方库PyInstaller的打包方法

    千次阅读 2019-03-12 00:37:44
    1 首先你需要安装PyInstaller第三方库,这里就不再对做赘述了
  • 2、python的第三方库,需要下载后安装到python的安装目录下,不同的第三方库安装及使用方法不同。3、它们调用方式是一样的,都需要用import语句调用。简单的说,一个是默认自带不需要下载安装的库,一个是需要下载...
  • linux下执行jar中的main方法时,提示缺少第三方jar包
  • 问题原因: 缺少第三方库SFML 解决办法: 导入第三方库 具体步骤:
  • 1.在项目开发中,总遇到...此办法已经可以应对大多数的情况,如果还是失败,请往下看二种方法: 2.如果还没有解决的话,在 Android Studio 的软件中,修改如下设置: File->Settings->Build, Execution...
  • 今天小编来给大家针对这个教大家qq第三方登陆授权失败110401怎么办的解决方法的问题来进行一个介绍,毕竟当下也是有诸多的小伙伴对于教大家qq第三方登陆授权失败110401怎么办的解决方法这个问题非常的重视的,那么在...
  • springboot 引入第三方jar包,注解无效(Configuration,Bean等无法生效) 原因:SpringBoot默认只扫描启动类所在包,第三方包自然不在此列(项目打包时,你能看到依赖包都在哪儿),也就无法被扫描到 解决办法:...
  • 用过ecplise的的都知道,遇到没有导入的包的时候,可以使用快捷键...那么在使用pycharm中,对于需要经常通过import导入第三方库的操作,可以使用以下的快捷键进行快速导入。 win: Alt + Enter mac: option + Enter
  • 参考文献 Gradle打可运行Jar包(包含依赖第三方库中的类) gradle 将依赖打入Jar包的方法 Gradle – Create a Jar file with dependencies +how to copy the dependencies libraries JARs in gradle The ...
  • 1、Enigma Virtual Box 下载https://enigmaprotector.com/en/downloads.html  2、opencv341... 参考的原文链接(未加入第三方库):https://blog.csdn.net/windsnow1/article/details/78004265 整理不易 点赞收藏关注喔~
  • Veins(车载通信仿真框架)入门教程(二)——调用第三方库 在借助Veins进行自己的研究时我们经常需要实现一些比较复杂的功能,有时就需要借助第三方库的帮助。 博主的研究需要使用神经网络,但是自己编写的效果不...
  • 1 跨域原因:浏览器同源策略         跨域指的是浏览器不能执行...同源策略它是由 Netscape 提出的一个安全策略,它是浏览器最核心也是最基本的安全功能,如果缺少同源策略,
  • python代码中含有第三方库,比如opencv时,需要指定库的路径,这会使pyinstaller将库打包进生成的exe中,否则运行exe时会出现缺少xxx库。 指令: pyinstaller -F -w -i skull.ico -p "D:\install file\python...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 96,390
精华内容 38,556
关键字:

缺少第三方登录