资讯专栏INFORMATION COLUMN

使用 Laravel Socialite 集成微信登录

hufeng / 3189人阅读

摘要:允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。这样,让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。

Laravel Socialite

Laravel Socialite provides an expressive, fluent interface to OAuth authentication with Facebook, Twitter, Google, LinkedIn, GitHub and Bitbucket. It handles almost all of the boilerplate social authentication code you are dreading writing.

Laravel Socialite 为第三方应用的 OAuth 认证提供了非常丰富友好的接口,我们使用它可以非常方便快捷的对类似微信、微博等第三方登录进行集成。

Open Authorization

OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。

OAuth 允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的 2 小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth 让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。

我们的应用与使用 OAuth 标准的第三方应用的交互流程一般是这样的:

展示跳转到第三方应用登录的链接

用户点击链接跳转到第三方应用登录并进行授权

在用户授权后第三方应用会跳转到我们所指定的应用回调资源地址并伴随用于交互 AccessToken 的 Code

我们的应用拿到 Code 后自主请求第三方应用并使用 Code 获取该用户的 AccessToken

获取 AccessToken 之后的应用即可自主的从第三方应用中获取用户的资源信息

Laravel Socialite UML

安装 Laravel Socialite

使用 Composer 进行安装:

composer require laravel/socialite
配置

你需要在 config/app.phpproviders 键中追加:

"providers" => [
    // Other service providers...

    LaravelSocialiteSocialiteServiceProvider::class,
],

aliasses 键中添加 Socialite:

"Socialite" => LaravelSocialiteFacadesSocialite::class,

config/services.php 配置文件中添加驱动器配置项:

"github" => [
    "client_id" => "your-github-app-id",
    "client_secret" => "your-github-app-secret",
    "redirect" => "http://your-callback-url",
],

至此整个流程安装完毕。

集成微信登录

集成微信我们需要提供一个 WechatServiceProvider 和 一个 WechatProvider,用这两个文件来为微信登录提供驱动,Laravel Socialite 的 SocialiteManager 继承自 IlluminateSupportManager 类,而其对自定义驱动提供了友好的接口支持,所以我们可以手动的添加一个 Wechat 驱动器:

openId = $openId;

        return $this;
    }

    /**
     * {@inheritdoc}.
     */
    protected $scopes = ["snsapi_login"];

    /**
     * {@inheritdoc}.
     */
    public function getAuthUrl($state)
    {
        return $this->buildAuthUrlFromBase("https://open.weixin.qq.com/connect/qrconnect", $state);
    }

    /**
     * {@inheritdoc}.
     */
    protected function buildAuthUrlFromBase($url, $state)
    {
        $query = http_build_query($this->getCodeFields($state), "", "&", $this->encodingType);

        return $url."?".$query."#wechat_redirect";
    }

    /**
     * {@inheritdoc}.
     */
    protected function getCodeFields($state = null)
    {
        return [
            "appid"         => $this->clientId, "redirect_uri" => $this->redirectUrl,
            "response_type" => "code", "scope"                 => $this->formatScopes($this->scopes, $this->scopeSeparator),
            "state"         => $state,
        ];
    }

    /**
     * {@inheritdoc}.
     */
    public function getTokenUrl()
    {
        return "https://api.weixin.qq.com/sns/oauth2/access_token";
    }

    /**
     * {@inheritdoc}.
     */
    public function getUserByToken($token)
    {
        $response = $this->getHttpClient()->get("https://api.weixin.qq.com/sns/userinfo", [
            "query" => [
                "access_token" => $token,
                "openid"       => $this->openId,
                "lang"         => "zh_CN",
            ],
        ]);

        return json_decode($response->getBody(), true);

    }

    /**
     * {@inheritdoc}.
     */
    public function mapUserToObject(array $user)
    {
        return (new User())->setRaw($user)->map([
          "openid" => $user["openid"], "nickname" => $user["nickname"],
          "avatar" => $user["headimgurl"], "name" => $user["nickname"],
          "email"  => null, "unionid"             => $user["unionid"]
        ]);
    }

    /**
    * {@inheritdoc}.
    */
    protected function getTokenFields($code)
    {
        return [
            "appid" => $this->clientId, "secret" => $this->clientSecret,
            "code" => $code, "grant_type" => "authorization_code",
        ];
    }

    /**
    * {@inheritdoc}.
    */
    public function getAccessTokenResponse($code)
    {
        $postKey = (version_compare(ClientInterface::VERSION, "6") === 1) ? "form_params" : "body";

        $response = $this->getHttpClient()->post($this->getTokenUrl(), [
            "headers" => ["Accept" => "application/json"],
            $postKey => $this->getTokenFields($code),
        ]);

        $responseBody = json_decode($response->getBody(), true);
        $this->setOpenId($responseBody["openid"]);

        return $responseBody;
    }
}

编写完驱动之后我们需要注册该驱动器到 SocialiteManager 中,因此我们编写一个 WechatServiceProvider:

app->make("LaravelSocialiteContractsFactory")->extend("wechat", function ($app) {
            $config = $app["config"]["services.wechat"];
            return new WechatProvider(
                $app["request"], $config["client_id"],
                $config["client_secret"], $config["redirect"]
            );
       });
    }
    public function register()
    {

    }
}

接着我们就可以添加配置项及将服务提供者注册到 Laravel 中:

// app.php
"providers" => [
    // Other service providers...
    CrowdfundingProvidersSocialiteWechatServiceProvider::class,
],

// services.php
"wechat" => [
    "client_id" => "appid",
    "client_secret" => "appSecret",
    "redirect" => "http://xxxxxx.proxy.qqbrowser.cc/oauth/callback/driver/wechat",
]

紧接着添加路由及控制器:

// route.php
Route::group(["middleware" => "web"], function () {
    Route::get("oauth/callback/driver/{driver}", "OAuthAuthorizationController@handleProviderCallback");
    Route::get("oauth/redirect/driver/{driver}", "OauthAuthorizationController@redirectToProvider");
});

控制器:

redirect();
    }

    public function handleProviderCallback($driver) {
        $user =  Socialite::driver($driver)->user();
        // dd($user)
    }

}

至此集成完毕。

PS: 欢迎关注简书 Laravel 专题,也欢迎 Laravel 相关文章的投稿 :),作者知识技能水平有限,如果你有更好的设计方案欢迎讨论 :)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/21859.html

相关文章

  • Laravel Socialite 详解

    摘要:这样,让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。 不久之前 Dearmadman 曾写过一篇 使用 Laravel Socialite 集成微信登录 的文章,但是似乎还是有些同学不太明白,询问着如何集成 QQ 登录,那么,本篇我们就来剖析一下 Laravel Socialite 的详细内容。让各位同学都获得 Laravel Socialite 所...

    yuanxin 评论0 收藏0
  • Laravel5.1 实现第三方登录认证(包括微博、QQ、微信、豆瓣)

    摘要:目前支持的认证有。英文不好的同学比如我,下面是中文文档通过扩展的,实现了很多第三方认证。国内的有微博微信豆瓣。至于和的具体值,这个是由新浪微博分发给你的,在新浪微博的授权回调页中填写。 前言 第三方登录认证能简化用户登录/注册的操作,降低用户登录/注册的门槛,对提高应用的用户转化率很有帮助。 Socialite Laravel 为我们提供了简单、易用的方式,使用 Laravel Soc...

    nifhlheimr 评论0 收藏0
  • 浅谈多个社交账号的绑定设计

    摘要:在详解中使用解决了第三方账号登录集成的问题,那么在获取到用户资料之后呢集成多个社交账号,该如何绑定同一个账号本篇就让我们来探讨一下集成登录的那点事。 Dearmadman 在 Laravel Socialite 详解 中使用 larastarscn/socialite 解决了第三方账号登录集成的问题,那么在获取到用户资料之后呢?集成多个社交账号,该如何绑定同一个账号?本篇就让我们来探讨...

    wean 评论0 收藏0
  • laravel package收集

    摘要:查找保存下载用搭建自己的缓存仓库权限管理的好选择基于封装的后台管理系统,支持手机和端访问支付宝风格的验证器后台系统微信接口的部署脚本开发的博客系统百度推送自动记录用户行为扩展一个项目管理系统根据生成对应导航的状态 1.debug https://github.com/barryvdh/l... showImg(https://segmentfault.com/img/bVmhWL); ...

    psychola 评论0 收藏0
  • Laravel优秀扩展包整理

    摘要:本文整理上国内相对较常用及以上版本的扩展包代码生成文档对象云存储文档消息闪存文档编辑器代码提示文档文档文档图片处理文档微信开发文档语言包文档验证码文档社会化登陆文档系统日志文档前端构建工具文档跨域资源共享文档基于的用户认 本文整理Github上国内相对较常用Laravel5及以上版本的扩展包 laravel-generator(代码生成) Github:https://github....

    lykops 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<