Symfony2框架实战教程——第四天:用HWIOAuthBundle实现第三方登录

为了方便用户能快速发布内容,我们只用要求QQ的第三方登录就行了。

如果你打算跟着我一起完成这个项目,可能会因为QQ需要验证你是否有个人域名而卡在这一章,我写了一篇不用OAuth的。但本篇文章也最好看看,大部分知识点是完全一样的。

使用HWIOAuthBundle实现第三方登录

可以想象得到,第三方登录这种常见需求,相关的库也是有的。这里我再推荐一个:HWIOAuthBundle

如同昨日,我们先将它通过Composer引入到我们项目当中:

1

2

$ composer require "hwi/oauth-bundle:0.4.*@dev"

并将其注册到AppKernel里:

1

2

3

4

5

6

7

8

9

10

// app/AppKernel.php

public function registerBundles()

{

$bundles = array(

// ...

new HWI\Bundle\OAuthBundle\HWIOAuthBundle(),

);

}

用过OAuth的同学应该知道,一个完整的OAuth客户端程序会包含许多链接。HWIOAuthBundle已经有一部分写好的路由,我们将它们引入到项目当中:

1

2

3

4

5

6

7

8

9

# app/config/routing.yml

hwi_oauth_redirect:

resource: "@HWIOAuthBundle/Resources/config/routing/redirect.xml"

prefix:   /connect

hwi_oauth_login:

resource: "@HWIOAuthBundle/Resources/config/routing/login.xml"

prefix:   /login

Bundle里可以自带路由规则以及对应的控制器,这也是Bundle的特点之一。

然后依照HWIOAuthBundle的文档,我们需要做一些配置:

1

2

3

4

5

# app/config/config.yml

hwi_oauth:

firewall_name: secured_area

此配置定义了需要使用HWIOAuthBundle登录后才能访问的地址。但是我们可以看到配置里并没有地址,只有一个防火墙名称,这是怎么一回事?先不用管我们接着添加配置:

1

2

3

4

5

6

7

8

9

10

# app/config/security.yml

security:

firewalls:

# ...

secured_area:

pattern: ^/

oauth:

login_path: hwi_oauth_connect

failure_path: hwi_oauth_connect

app/config/security.yml是专门用来配置用户访问权限的文件。其中firewalls里定义了若干防火墙。可以看到,第一个防火墙就是刚才配置的防火墙名称。

secured_area防火墙里,可以定义此防火墙作用的路径。由于开启了HWIOAuthBundle的缘故,防火墙可以支持oauth配置,里面定义了登录路径login_path,登录失败去的路径failure_path,他们的值都是HWIOAuthBundle用来登录的路由名。这里教大家一个实用的命令,可以查看当前项目里都已经定义了哪些路由:

1

2

$ php app/console debug:router

最后还有一个oauth_user_provider选项,目前我们暂时不用管它。

如果您是按步骤看到这里来的,你会发现在firewalls里还定义了其他的防火墙devdemo_logindemo_secure_area。因为之前被删掉的AcmeDemoBundle自带了权限控制和登录表单的演示,所以定义了两个demo_***的防火墙,目前已经可以放心删除。最后还剩一个dev防火墙,可以看到它定义了静态文件目录css|images|js可以不需要通过防火墙就能访问,另外_(profiler|wdt)这两个目录包含了开放工具的访问路径,也没有必要受防火墙的保护。

这里还需要注意防火墙定义的顺序和有限级:配置位置越靠前,优先级越高,比如说当用户访问一个路径/css/main.css的时候,第一个防火墙配置(虽然此配置其实是用来关闭防火墙的……)已经生效,就不会再往下匹配了。

HWIOAuthBundle已经帮我们做了很多代码上的工作,比如QQ的OAuth登录地址是什么,参数名是什么……这些 HWIOAuthBundle都已经帮我们设置好了,我们需要做的仅仅是定义一个OAuth服务端,告诉HWIOAuthBundle帐号是谁提供的(这 里有一个HWIOAuthBundle目前支持的OAuth服务端列表),以及设置api_key和api_secret:

1

2

3

4

5

6

7

8

9

# app/config/config.yml

hwi_oauth:

resource_owners:

# owner的名字可以随便取,只要是唯一的名字就行

qq:

type:                qq

client_id:           <client_id>

client_secret:       <client_secret>

定义好OAuth服务端后,我们再在secured_area防火墙里将OAuth服务端的回调地址设置上:

1

2

3

4

5

6

7

8

9

# app/config/security.yml

security:

firewalls:

# ...

secured_area:

oauth:

resource_owners:

qq: check_qq

注意这里的resource_owners其实指的是resource_owner callback path,作者完全可以取一个更准确的名字。

目前我们还没有定义名为check_qq的路由,赶紧加上:

1

2

3

4

# app/config/routing.yml

check_qq:

pattern: /login/check-qq

我们可以发现,这里并没有为某个路径对应一个控制器,这又是怎么一回事?我只先透露通过事件监听器是可以做到的,目前就不多说了。

让我们再回到security.yml文件。这里再简单说说firewall的设计思想。每一个firewall都会定义了以下一些事情:

  1. 是开启还是关闭firewall,如果security: false,就是指此firewall是被关闭的,比如dev防火墙
  2. 哪些路径适用于此firewall规则,这通过pattern来指定,可以参考dev防火墙的配置
  3. 如果用户没有登录,将以什么方式登录,比如常见的使用登录表单的方式,如果使用此种方式,还要定义将引导用户去什么路径登录,以及那个路径是用来 检查用户登录信息输入的。这里需要注意的是,登录页面的路径是不可以被防火墙保护起来的(不过有一种情况除外,后面再说),原因我就不说了吧,还是很容易 想到的。

其他还有很多控制行为细节和技术细节的东西,这里就不多说了,遇到的时候自然会说的。

在用户没有登录的时候,开发工具栏也会有显示,方便大家了解当前的登录状态,未登录的时候将会如下显示

在使用防火墙的路径访问时,Symfony检查访问者一个叫做Auth Token的东西,就好象武侠片里的太监进皇宫,手里得有令牌证明自己的身份一样。要想取得令牌,就得去登录页面登录获取。防火墙的工作也及其简单:带着 令牌的,欢迎!没有令牌?出去!只不过,有一种情况除外,那就是防火墙可以设置未登录的访问者,各个都自动颁发一个叫anonymous auth token的东西,匿名访问。此时虽然用户并没有真正登录,但是却跟登录的状态一样。如果是这样一种配置,等于防火墙是都放行的,所以还需要一个叫access_control的东西,来检查每一个用户拿的都是什么样的令牌,可以做什么样的事情。

知道了以上概念,可以说,做身份检查其实可以有两种风格,第一种风格,不登录没有令牌,配置好防火墙的访问路径,将不能公开访问的”皇宫“用墙直接隔开起来;第二种风格,大家都可以进,通过权限控制的方式来限制”某些身份不明不白的人“的行为。

我个人是比较喜欢第一种方式。我喜欢让防火墙检查用户”你是谁“,而让访问控制器检查”你能做什么“这种明确的分工方式,而且,本来就是公开的区域 还需要给用户创建”令牌“对象我觉得是一个比较浪费的做法。不过,因为HWIOAuthBundle在登录界面的时候,必须要检查Auth Token(按理来说应该先检查有没有Auth Token,再检查Auth Token是什么身份),这里我们只能采用第二种方式。

我们将让secured_area可以匿名访问(还叫secured这样好吗……)

1

2

3

4

5

6

# app/config/security.yml

security:

firewalls:

secured_area:

anonymous: ~

然后在access_control里设置,在创建新闻以及修改新闻的时候,要求必须登录:

1

2

3

4

5

# app/config/security.yml

security:

access_control:

- { path: ^/news/(new|(\d+\/edit)), roles: IS_AUTHENTICATED_FULLY }

到此,我们权限相关的配置已经完成了。

不过,事情还是没结束……在Symfony2的世界里,每一个在网站访问的登录用户,都需要一个叫做User Provider的东西来生成,在Symfony2里UserProvider都需要实现UserProviderInterface,我们只需要实现此接口,返回一个Symfony2的用户对象就行。不过还好HWIOAuthBundle已经帮我们实现了这个接口,并且已经为其定义好了服务,我们只用使用它就可以了:

1

2

3

4

5

6

7

8

9

10

11

12

# app/config/security.yml

security:

providers:

oauth:

id: hwi_oauth.user.provider

firewalls:

secured_area:

oauth:

oauth_user_provider:

service: hwi_oauth.user.provider

好吧,其实我也不知道为什么要配置两次……

事情到这个地步,还没有结束……好吧,其实已经结束了。现在我们可以访问一下/news路径,看看是不是会自动跳转到/login页面,是否会从QQ网站登录并成功返回登录的用户名:

可以看到,虽然HWIOAuthBundle有这样那样的问题,但是不得不承认,它还是极大的提高了开发的效率。

最后记得将测试用的in_memory类型的user provider删掉。

时间: 2024-08-10 23:30:35

Symfony2框架实战教程——第四天:用HWIOAuthBundle实现第三方登录的相关文章

Symfony2框架实战教程——第五天:KnpMenuBundle创建菜单项+结合Twitter Boostrap3

做界面最好从交互比较多的页面入手,目前交互元素比较丰富的,有新闻列表页和新闻显示页. 为了开发快速,但也不会让界面太难看,我打算直接用Twitter Boostrap3了. 如果是看过我前几期文章的同学一定能猜得到,我一定又要说:“是的,像boostrap3这种常用的前端开发框架,相应的Bundle也是有的”.没错!这次我向大家推荐MopaBootstrapBundle,里面包含了使用LESS/SASS编译Boostrap CSS,支持让Symfony2框架以及常见Bundle比如我们的用过的K

Symfony2框架实战教程——第一天:创建项目

Symfony2的教程非常的详尽,但是却不太亲近新手.新手想要完全理解Symfony2文档的内容,需要对互联网开发有一定工作经验才行,否则 总是有一种看不太明白,看完了也不不知道从哪儿开始的感觉.如果你有这种感觉,希望这篇文章能让你快速上手,本篇的目的,就是为了让Symfony2新 手,甚至是PHP新手能快速开始一个具体的项目. 本篇系列重点是为了带领新手使用Symfony2框架,如果您想了解的是Symfony2组件,可阅读我翻译Symfony2项目组老大的系列教程<使用Symfony2组件创建

Symfony2框架实战教程——第六天:模板重载与翻译

在未登录状态下点击“+发表新闻”按钮,也就是/news/new链接,会转跳到/oauth/login/链接,也就是第三方登录的链接(如果只实现了本地用户登录的同学,去的应该是另外一个界面,不过没关系,重载模板的原理都一样).目前第三方登录页面只有一个可怜巴巴的“QQ”这个链接,让我们也给它加上页头页尾. 不过,这个模板文件很明显不是我们自己添加的,是第三方Bundle里自带的,难道我们要去修改第三方Bundle的代码吗?库文件随便修改这样好吗?当然不好,好消息是Symfony2框架实际是提供了框

Symfony2框架实战教程——第三天:用KnpPaginatorBundle实现翻页

创建业务数据模型 新闻数据算是我们业务模型里必不可少的模型之一.根据我们之前对需求的分析,我们可以很容易想到,新闻模型News需要的属性: 标题属性 文本属性 接下来,我们要在AppBundle里创建它,但是这些数据还需要一个持久层来保存数据,例如之前配置的Mysql.目前流行的开发方式,无论是Java还是ROR,都会使用ORM将数据库字段和类属性关联起来. Symfony2框架本身并不包含ORM工具(严格意义上来说,Symfony2框架,即FrameworkBundle,不包含ORM,安全组

Symfony2框架实战教程——第二天:创建新页面

在此之前,我们先明确一下我们要实现什么功能,在开始开展具体的代码工作前先明确自己的目标是一个节省时间的好习惯.我们的需求如下: 用户可以使用新浪微博或者QQ帐号登录. 用户可以投稿,需要填写的内容为“标题”+“正文” 用户可以对某篇文章进行评论 在以上的基础上,我们继续具体化我们的需求: 用户的内容都将使用markdown格式 评论内容不可超过140个字 新闻内容不可超过5000个字 标题内容不可超过70个字 好,到这里我们的需求已经很明确了,虽然简单得似乎不可能会有人用的样子- 修改配置文件

Symfony2框架实战教程——第六天#Alt:验证码

如果读者是从表世界过来的,应该知道怎么通过重载模板来改变第三方Bundle提供的模板.这里我们将重载用户登录页面作为作业留给大家,我们先来重载注册页面,不过为了提供新鲜的知识点,我们这次除了要装修注册页面以外,还要求给注册页面提供验证码. 对于我这种收集bundle的高手,自然少不了推荐验证码相关的bundle:GregwarCaptchaBundle 一如既往安装Bundle 1 2 $ composer require gregwar/captcha-bundle 一如既往注册Bundle

Java之框架实战教程

开发快报: 页面打印功能,websocket 强制下线功能,玩转websocket技术  [金牌]获取[下载地址]   QQ: 313596790A 代码生成器(开发利器);     增删改查的处理类,service层,mybatis的xml,SQL( mysql   和oracle)脚本,   jsp页面 都生成   就不用写搬砖的代码了,生成的放到项目里,可以直接运行B 阿里巴巴数据库连接池druid;  数据库连接池  阿里巴巴的 druid.Druid在监控.可扩展性.稳定性和性能方面都

机器学习实战教程(四):朴素贝叶斯基础篇之言论过滤器

原文链接: Jack-Cui,https://cuijiahua.com/blog/2017/11/ml_4_bayes_1.html 一.前言 朴素贝叶斯算法是有监督的学习算法,解决的是分类问题,如客户是否流失.是否值得投资.信用等级评定等多分类问题.该算法的优点在于简单易懂.学习效率高.在某些领域的分类问题中能够与决策树.神经网络相媲美.但由于该算法以自变量之间的独立(条件特征独立)性和连续变量的正态性假设为前提,就会导致算法精度在某种程度上受影响. 本篇文章将从朴素贝叶斯推断原理开始讲起,

应用程序框架实战三十四:数据传输对象(DTO)介绍及各类型实体比较(转)

本文将介绍DDD分层架构中广泛使用的数据传输对象Dto,并且与领域实体Entity,查询实体QueryObject,视图实体ViewModel等几种实体进行比较. 领域实体为何不能一统江湖? 当你阅读我或其它博主提供的示例代码时,会发现几种类型的实体,这几种实体初步看上去区别不大,只是名称不同,特别在这些示例非常简单的情况下更是如此.你可能会疑惑为何要搞得这么复杂,采用一种实体不是更好? 在最理想的情况下,我们只想采用领域实体Entity进行所有的操作. 领域实体是领域层的核心,是业务逻辑的主要