资讯专栏INFORMATION COLUMN

搭建OAuth2.0

Cheriselalala / 1885人阅读

摘要:原因使用简单,可以很快上手,文档齐全,功能完善。请求,端对应的模板里是告知用户,即将授予的权限列表,以及是否允许授权的按钮。请求,端获取用户资源各种授权类型,都可以很方便支持。

前奏

系统:Ubuntu
语言:PHP7
框架:YAF
OAuth2.0:bshaffer/oauth2-server-php

OAuth2.0 有很多开源代码库

Github 排名前两位

thephpleague/oauth2-server
bshaffer/oauth2-server-php

本文使用的是第二个:bshaffer。原因:使用简单,可以很快上手,文档齐全,功能完善。

wiki: https://bshaffer.github.io/oa...
github: https://github.com/bshaffer/o...

引入 OAuth2.0 的 Server 端源代码

编辑 Composer.json 文件

{
    "require": {
        "bshaffer/oauth2-server-php" : "v1.10.0"
    }
}

yaf框架结构

├── application
│   └── modules
│       └── User
│           ├── controllers
│           │   └── Oauth.php
│           └── views
│               └── oauth
│                   ├── authorize.php
│                   ├── auth.php
│                   ├── index.php
│                   └── resource.php
├── Bootstrap.php
├── cli
├── composer.json
├── composer.lock
├── composer.phar
├── conf
├── docs
├── public
└── vendor

Yaf 框架中,在 Bootstrap.php 文件中自动加载 OAuth2.0

public function _initLoader(Yaf_Dispatcher $dispatcher)
{
    include(APP_PATH . "/vendor/autoload.php");
}

新建一个 Controller 文件:Oauth.php,在里面建立几个 Action

AuthorizeAction()   服务端:提供授权
TokenAction()       服务端:提供Token
ResourceAction()    服务端:提供资源
IndexAction()       客户端:模拟第三方接入
_server()           服务端:初始化服务器相关,如:存储,这里采用mysql

命名空间

use OAuth2Server;
use OAuth2StoragePdo;
use OAuth2GrantTypeAuthorizationCode;
use OAuth2GrantTypeClientCredentials;
use OAuth2GrantTypeUserCredentials;
use OAuth2Request;
use OAuth2Response;

_server() 函数代码

private function _server()
{
    $dbParams = array(
        "dsn"      => "mysql:host=127.0.0.1;port=3306;dbname=oauth;charset=utf8;",
        "username" => "root",
        "password" => "123456",
    );

    // $dsn is the Data Source Name for your database, for exmaple "mysql:dbname=my_oauth2_db;host=localhost"
    $storage = new Pdo($dbParams);

    // Pass a storage object or array of storage objects to the OAuth2 server class
    $server = new Server($storage);

    // Add the "Client Credentials" grant type (it is the simplest of the grant types)
    $server->addGrantType(new ClientCredentials($storage));

    // Add the "Authorization Code" grant type (this is where the oauth magic happens)
    $server->addGrantType(new AuthorizationCode($storage));

    return $server;
}

IndexAction() 代码

public function indexAction()
{
    $uri   = $_SERVER["QUERY_STRING"];
    $code  = substr($uri, strpos($uri, "code=")+5, 40);
    $state = substr($uri, strpos($uri, "state=")+6);

    if ($code) {
        $params = array(
            "code"          => $code,
            "state"         => $state,
            "client_id"     => "client_id",
            "client_secret" => "client_secret",
            "grant_type"    => "authorization_code",
            "scope"         => "basic",
            "redirect_uri"  => "http://yourhost/user/oauth/index",
        );
        
        $url = "http://yourhost/user/oauth/token";

        $result = $this->httpPost($url, $params);
        $result = json_decode($result, true);

        //写入Session,便于测试
        Yaf_Session::getInstance()->set("access_token",$result["access_token"]);
        return false;
    } else {
        //客户端请求授权之前,页面中展示一个链接,用户点后,可以跳转至服务端的授权页面。
        $this->getView()->assign("data", array())->render("oauth/index.php");
    }
}

对应的模板代码:oauth/index.php


AuthorizeAction() 代码

/**
 * 展示授权页面,用户可以点击同意进行授权
 */
public function AuthorizeAction()
{
    $request = Request::createFromGlobals();
    $is_authorized = $request->request("is_authorized") ? true : false;

    //判断用户是否同意授权
    if ($is_authorized) {

        $response = new Response();
        $server = $this->_server();

        // validate the authorize request
        if (!$server->validateAuthorizeRequest($request, $response)) {
            $response->send();
            die;
        }

        $server->handleAuthorizeRequest($request, $response, $is_authorized)->send();

        return false;
    }

    //将请求授权中带来的各个参数,写入授权页中的变量,用以授权表单POST提交。
    $renderData = $_GET;
    $this->getView()->assign("data", $renderData)->render("oauth/authorize.php");
}

用户授权页面:oauth/authorize.php




    
    直达天庭 - 南天门
    
    

有 1 个你关注的人连接
将允许人间进行以下操作:
  • 获得你的个人信息,好友关系
  • 分享内容到你的微博
  • 获得你的评论

TokenAction()

/**
 * 返回JSON结构数据
 * {
        access_token: "977b1077556e9b23ff07ef7606a5eaf947f27d41",
        expires_in: 3600,
        token_type: "Bearer",
        scope: "basic",
        refresh_token: "d2367887bdd743121adfe5fda5083064439f1cb1"
    }
 */
public function TokenAction()
{
    $server = $this->_server();
    $server->handleTokenRequest(Request::createFromGlobals())->send();
    return false;
}

ResourceAction() 代码

public function ResourceAction()
{
    $server = $this->_server();

    //获取授权用户Session中保存的access_token,用access_token可以请求权限范围内的所有接口
    $_POST["access_token"] = Yaf_Session::getInstance()->get("access_token");
    
    // Handle a request to a resource and authenticate the access token
    if (!$server->verifyResourceRequest(Request::createFromGlobals())) {
        $server->getResponse()->send();
        die;
    }
    echo json_encode(array("success" => true, "message" => "You accessed my APIs!"));
    return false;
}

请求用户资源:/user/oauth/resource

{
    success: true,
    message: "You accessed my APIs!"
}

实现思路:

URL请求:/user/oauth/index,Client端

对应的模板里放置一个链接,用以跳转至服务端的授权认证页面/user/oauth/authorize。授权成功后,服务端会将对应的code和state参数,附在回调的redirect_uri里,即:/user/oauth/index?code=fcd6a9589e7ab43398e4e5349b23846babc79fab&state=xxx,在indexAction中解析出回调的code,用以请求接口/user/oauth/token,来交换access_token。

URL请求:/user/oauth/authorize,Server端
对应的模板里是告知用户,即将授予的权限列表,以及是否允许授权的按钮。

URL请求:/user/oauth/token,Server端
获取access_token。

URL请求:/user/oauth/resource,Server端
获取用户资源

LAST:

各种授权类型,都可以很方便支持。

数据存储层,也可以随意切换,比如切换为 Redis

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

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

相关文章

  • 从零开始用 Flask 搭建一个网站(四)

    摘要:前言从零开始用搭建一个网站三介绍了网页前端与后端前端与前端之间数据的交流。作者极光为极光团队账号,欢迎关注原文从零开始用搭建一个网站四知乎专栏极光日报 前言 从零开始用 Flask 搭建一个网站(三) 介绍了网页前端与后端、前端与前端之间数据的交流。本节主要介绍一下如何应用 Flask-OAuthlib, 使用 Flask-OAuthlib 就可以轻松地请求第三方应用提供的 API 。...

    CarterLi 评论0 收藏0
  • Spring Cloud 上手实战-架构解析及实作

    摘要:服务器将要监听的端口不要使用服务进行注册不要在本地缓存注册表信息使用一个新的注解,就可以让我们的服务成为一个服务服务发现客户端配置以为例需要做件事情成为服务发现的客户端配置对应来说我们只需要配置如下启动运行查看。 Spring简介 为什么要使用微服务 单体应用: 目前为止绝大部分的web应用软件采用单体应用,所有的应用的用户UI、业务逻辑、数据库访问都打包在一个应用程序上。 showI...

    Godtoy 评论0 收藏0
  • OAuth2基本概念和运作流程

    摘要:目前的版本是版,本文将对的一些基本概念和运行流程做一个简要介绍。只要有一个第三方应用程序被破解,就会导致用户密码泄漏,以及所有被密码保护的数据泄漏。运行流程客户端向资源所有者请求授权。 OAuth(开放授权)是一个关于授权的开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。目前的版本是2.0版,本文将...

    wyk1184 评论0 收藏0

发表评论

0条评论

Cheriselalala

|高级讲师

TA的文章

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