Github 第三方登录插件#
功能介绍#
配置Github插件后,可以点击ArkID登录页面的Github图标,跳转到Github网站完成Oauth2认证,并和ArkID的用户绑定
创建Github应用#
创建ArkID第三方登录配置,获取回调URL#
更新Github应用回调URL,点击登录按钮#
实现思路#
需要覆盖插件基类的抽象方法,插件基类见arkid.core.extension.extrnal_idp.ExternalIdpExtension
统一绑定和解绑说明#
请参见三方账号绑定
抽象方法实现:#
代码#
        
extension_root.com_longgui_external_idp_github.ExternalIdpGithubExtension            (ExternalIdpExtension)
        
#
    Source code in extension_root/com_longgui_external_idp_github/__init__.py
          class ExternalIdpGithubExtension(ExternalIdpExtension):
    def load(self):
        super().load()
        self.register_extend_field(GithubUser, "github_user_id")
        self.register_extend_field(GithubUser, "github_nickname")
        self.register_extend_field(GithubUser, "github_avatar")
        self.register_external_idp_schema("github", GithubConfigSchema)
    def get_img_url(self):
        """
        返回Github的图标URL
        """
        return IMG_URL
    def get_auth_code_from_request(self, request):
        code = request.GET.get("code", '')
        return code
    def get_authorize_url(self, config, callback_url, next_url):
        """
        Args:
            config (arkid.core.extension.TenantExtensionConfig): 第三方登录的插件运行时配置
            redirect_uri (str): 在ArkID中创建Github登录配置后返回的回调地址
        Returns:
            str: 返回用于向Github发起认证的URL
        """
        redirect_uri = "{}{}".format(callback_url, next_url)
        redirect_uri = quote(redirect_uri)
        url = "{}?client_id={}&redirect_uri={}".format(
            AUTHORIZE_URL,
            config.config.get("client_id"),
            redirect_uri,
        )
        return url
    def get_ext_token(self, config, code):
        """
        Args:
            config (arkid.core.extension.TenantExtensionConfig): 第三方登录的插件运行时配置
            code (str): Github返回的授权码
        Returns:
            str: 返回Github返回的access_token
        """
        response = requests.post(
            GET_TOKEN_URL,
            params={
                "code": code,
                "client_id": config.config.get("client_id"),
                "client_secret": config.config.get("client_secret"),
                "grant_type": "authorization_code",
            },
        ).__getattribute__("_content")
        result = dict(
            [(k, v[0]) for k, v in parse_qs(response.decode()).items()]
        )  # 将响应信息转换为字典
        return result["access_token"]
    def get_ext_user_info(self, config, code, token):
        """
        Args:
            config (arkid.core.extension.TenantExtensionConfig): 第三方登录的插件运行时配置
            code (str): Github返回的授权码
            token (str): Github返回的access_token
        Returns:
            tuple: 返回Github中用户信息中的id, login,avatar_url和所有用户信息
        """
        headers = {"Authorization": "token " + token}
        response = requests.get(
            GET_USERINFO_URL,
            params={"access_token": token},
            headers=headers,
        ).json()
        return response["id"], response["login"], response["avatar_url"], response
    def get_arkid_user(self, ext_id):
        """
        Args:
            ext_id (str): 从Github用户信息接口获取的用户标识
        Returns:
            arkid.core.models.User: 返回ext_id绑定的ArkID用户
        """
        github_user = GithubUser.valid_objects.filter(github_user_id=ext_id).first()
        if github_user:
            return github_user.target
        else:
            return None
    def bind_arkid_user(self, ext_id, user, data):
        """
        Args:
            ext_id (str): 从Github用户信息接口获取的用户标识
            user (arkid.core.models.User): 用于绑定的ArkID用户
            data (dict) request数据
        """
        user.github_user_id = ext_id
        user.github_nickname = data.get('ext_name', '')
        user.github_avatar = data.get('ext_icon', '')
        user.save()
    def get_img_and_redirect_url(self, config):
        return config.config.get("img_url", ""), config.config.get("login_url", "")
bind_arkid_user(self, ext_id, user, data)
#
    Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
| ext_id | str | 从Github用户信息接口获取的用户标识 | required | 
| user | arkid.core.models.User | 用于绑定的ArkID用户 | required | 
Source code in extension_root/com_longgui_external_idp_github/__init__.py
          
        
get_arkid_user(self, ext_id)
#
    Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
| ext_id | str | 从Github用户信息接口获取的用户标识 | required | 
Returns:
| Type | Description | 
|---|---|
| arkid.core.models.User | 返回ext_id绑定的ArkID用户 | 
Source code in extension_root/com_longgui_external_idp_github/__init__.py
          
        
get_auth_code_from_request(self, request)
#
    
  
get_authorize_url(self, config, callback_url, next_url)
#
    Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
| config | arkid.core.extension.TenantExtensionConfig | 第三方登录的插件运行时配置 | required | 
| redirect_uri | str | 在ArkID中创建Github登录配置后返回的回调地址 | required | 
Returns:
| Type | Description | 
|---|---|
| str | 返回用于向Github发起认证的URL | 
Source code in extension_root/com_longgui_external_idp_github/__init__.py
          def get_authorize_url(self, config, callback_url, next_url):
    """
    Args:
        config (arkid.core.extension.TenantExtensionConfig): 第三方登录的插件运行时配置
        redirect_uri (str): 在ArkID中创建Github登录配置后返回的回调地址
    Returns:
        str: 返回用于向Github发起认证的URL
    """
    redirect_uri = "{}{}".format(callback_url, next_url)
    redirect_uri = quote(redirect_uri)
    url = "{}?client_id={}&redirect_uri={}".format(
        AUTHORIZE_URL,
        config.config.get("client_id"),
        redirect_uri,
    )
    return url
get_ext_token(self, config, code)
#
    Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
| config | arkid.core.extension.TenantExtensionConfig | 第三方登录的插件运行时配置 | required | 
| code | str | Github返回的授权码 | required | 
Returns:
| Type | Description | 
|---|---|
| str | 返回Github返回的access_token | 
Source code in extension_root/com_longgui_external_idp_github/__init__.py
          def get_ext_token(self, config, code):
    """
    Args:
        config (arkid.core.extension.TenantExtensionConfig): 第三方登录的插件运行时配置
        code (str): Github返回的授权码
    Returns:
        str: 返回Github返回的access_token
    """
    response = requests.post(
        GET_TOKEN_URL,
        params={
            "code": code,
            "client_id": config.config.get("client_id"),
            "client_secret": config.config.get("client_secret"),
            "grant_type": "authorization_code",
        },
    ).__getattribute__("_content")
    result = dict(
        [(k, v[0]) for k, v in parse_qs(response.decode()).items()]
    )  # 将响应信息转换为字典
    return result["access_token"]
get_ext_user_info(self, config, code, token)
#
    Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
| config | arkid.core.extension.TenantExtensionConfig | 第三方登录的插件运行时配置 | required | 
| code | str | Github返回的授权码 | required | 
| token | str | Github返回的access_token | required | 
Returns:
| Type | Description | 
|---|---|
| tuple | 返回Github中用户信息中的id, login,avatar_url和所有用户信息 | 
Source code in extension_root/com_longgui_external_idp_github/__init__.py
          def get_ext_user_info(self, config, code, token):
    """
    Args:
        config (arkid.core.extension.TenantExtensionConfig): 第三方登录的插件运行时配置
        code (str): Github返回的授权码
        token (str): Github返回的access_token
    Returns:
        tuple: 返回Github中用户信息中的id, login,avatar_url和所有用户信息
    """
    headers = {"Authorization": "token " + token}
    response = requests.get(
        GET_USERINFO_URL,
        params={"access_token": token},
        headers=headers,
    ).json()
    return response["id"], response["login"], response["avatar_url"], response
get_img_and_redirect_url(self, config)
#
    返回前端渲染第三方登录的按钮 抽象方法
Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
| config | arkid.extension.models.TenantExtensionConfig | 第三方认证提供的Client_ID, | required | 
Returns:
| Type | Description | 
|---|---|
| tuple | 返回图片url和跳转地址('image_url', 'redirect_url') | 
get_img_url(self)
#
    
  
load(self)
#
    抽象方法,插件加载的入口方法









