yii2获取登录前的页面url地址--电脑和微信浏览器上的实现以及yii2相关源码的学习
2016-12-12 21:00
821 查看
对于一个有登录限制(权限限制)的网站,用户输入身份验证信息以后,验证成功后跳转到登录前的页面是一项很人性化的功能。那么获取登录前的页面地址就很关键,今天在做一个yii2项目的登录调试时发现了一些很有意思的问题,记录下来。
1,场景描述
网站SiteA上的页面Page2需要登录后才能查看,Page2的链接放在页面Page1的一个按钮Button上,Page1在登录前后都是可以访问的,SiteA只提供了微信扫码登录的入口。
2,功能需求
假定访客User已经在SiteA上注册过,但当前未登录。User在浏览Page1时,如果点击页面内的Button,则会来到扫码登录页。用微信扫码登录成功后则会跳转至Page2。
3,跳转页面的代码
在微信授权后要回调的地址中设置好控制器controller和方法callback。
然后在callback方法中进行用户登录后的逻辑编写,如果登录成功:
这么写在电脑的浏览器上访问网站时是没有问题的,可以实现上述的功能需求。但是如果User是用手机在微信中访问SiteA的Page1,然后点击了Button,那么他是不是会像在电脑上那样来到Page2呢?
今天测试了下,没有跳转到Page2,反而来到了网站的首页。至于原因是什么,现在还不太清楚。不过倒是找到了解决的方法:在微信授权后要回调地址的地址中加上state参数,在state参数中附带上User登录前浏览的页面地址url。这样在callback方法中就可以拿到url,上面登录成功后的页面跳转就可以这么写:
4,User登录前浏览的页面地址url该怎么获得
yii2中提供了一个方法,下面的方法就可以获得登录前的页面url。
5,yii2是如何实现4中的方法和功能的呢?
4中的方法是在yii\web\User中定义的:
第3行yii\web\Session的get方法:
可以看到yii2是从session中获取的 $this->returnUrlParam 作为登录前的浏览页面地址。
那么它是如何存储的session,又是在什么时间存储的呢?答案都在yii\web\User和yii\webSession中。
yii\web\User中的setReturnUrl()方法:
yii\web\User中的loginRequired()方法中调用了setReturnUrl()方法:
然后在yii\filters\AccessControl中的denyAccess()中又调用了loginRequired()
然后在yii\filters\AccessControl中的beforeAction()中又调用了denyAccess()。
AccessControl可以配置在控制器中,也可以配置在yii2应用的配置文件main.php中,如果配置了,那么在每一次调用控制器的action之前都会执行这个beforeAction(),也就会触发session的存储。
yii\web\User中设置了默认要存储的url键名
可以看下session中的内容验证下:
6,再来看下3中的$this->goBack()方法
yii\web\Contorller中
可以看到它也是跳转到从 Yii::$app->getUser()->getReturnUrl() 获取的url,其实也就是从session中获取的url地址。
7,疑问
那么上面的讨论都是基于登录操作(涉及到了登录前后的逻辑),如果一个网站没有登录功能,也用不到权限控制(AccessControl),就更不用session存储url了。嗯,应该是这么回事。不用登录操作的话,也就不会涉及到刚开始提到的页面跳转了。
完
1,场景描述
网站SiteA上的页面Page2需要登录后才能查看,Page2的链接放在页面Page1的一个按钮Button上,Page1在登录前后都是可以访问的,SiteA只提供了微信扫码登录的入口。
2,功能需求
假定访客User已经在SiteA上注册过,但当前未登录。User在浏览Page1时,如果点击页面内的Button,则会来到扫码登录页。用微信扫码登录成功后则会跳转至Page2。
3,跳转页面的代码
在微信授权后要回调的地址中设置好控制器controller和方法callback。
然后在callback方法中进行用户登录后的逻辑编写,如果登录成功:
return $this->goBack();
这么写在电脑的浏览器上访问网站时是没有问题的,可以实现上述的功能需求。但是如果User是用手机在微信中访问SiteA的Page1,然后点击了Button,那么他是不是会像在电脑上那样来到Page2呢?
今天测试了下,没有跳转到Page2,反而来到了网站的首页。至于原因是什么,现在还不太清楚。不过倒是找到了解决的方法:在微信授权后要回调地址的地址中加上state参数,在state参数中附带上User登录前浏览的页面地址url。这样在callback方法中就可以拿到url,上面登录成功后的页面跳转就可以这么写:
if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') === false) { // User在pc浏览器中的跳转 return $this->goBack(); } else { // User在微信浏览器中的跳转 return $this->redirect(url); }
4,User登录前浏览的页面地址url该怎么获得
yii2中提供了一个方法,下面的方法就可以获得登录前的页面url。
Yii::$app->user->returnUrl;
5,yii2是如何实现4中的方法和功能的呢?
4中的方法是在yii\web\User中定义的:
public function getReturnUrl($defaultUrl = null) { $url = Yii::$app->getSession()->get($this->returnUrlParam, $defaultUrl); if (is_array($url)) { if (isset($url[0])) { return Yii::$app->getUrlManager()->createUrl($url); } else { $url = null; } } return $url === null ? Yii::$app->getHomeUrl() : $url; }
第3行yii\web\Session的get方法:
public function get($key, $defaultValue = null) { $this->open(); return isset($_SESSION[$key]) ? $_SESSION[$key] : $defaultValue; }
可以看到yii2是从session中获取的 $this->returnUrlParam 作为登录前的浏览页面地址。
那么它是如何存储的session,又是在什么时间存储的呢?答案都在yii\web\User和yii\webSession中。
yii\web\User中的setReturnUrl()方法:
public function setReturnUrl($url) { Yii::$app->getSession()->set($this->returnUrlParam, $url); }
yii\web\User中的loginRequired()方法中调用了setReturnUrl()方法:
public function loginRequired($checkAjax = true, $checkAcceptHeader = true) { $request = Yii::$app->getRequest(); $canRedirect = !$checkAcceptHeader || $this->checkRedirectAcceptable(); if ($this->enableSession && $request->getIsGet() && (!$checkAjax || !$request->getIsAjax()) && $canRedirect ) { $this->setReturnUrl($request->getUrl()); } // ......省略的代码 }
然后在yii\filters\AccessControl中的denyAccess()中又调用了loginRequired()
protected function denyAccess($user) { if ($user->getIsGuest()) { $user->loginRequired(); } else { throw new ForbiddenHttpException(Yii::t('yii', 'You are not allowed to perform this action.')); } }
然后在yii\filters\AccessControl中的beforeAction()中又调用了denyAccess()。
AccessControl可以配置在控制器中,也可以配置在yii2应用的配置文件main.php中,如果配置了,那么在每一次调用控制器的action之前都会执行这个beforeAction(),也就会触发session的存储。
yii\web\User中设置了默认要存储的url键名
public $returnUrlParam = '__returnUrl';
可以看下session中的内容验证下:
__returnUrl|s:29:"/controller/action?id=value";
6,再来看下3中的$this->goBack()方法
yii\web\Contorller中
public function goBack($defaultUrl = null) { return Yii::$app->getResponse()->redirect(Yii::$app->getUser()->getReturnUrl($defaultUrl)); }
可以看到它也是跳转到从 Yii::$app->getUser()->getReturnUrl() 获取的url,其实也就是从session中获取的url地址。
7,疑问
那么上面的讨论都是基于登录操作(涉及到了登录前后的逻辑),如果一个网站没有登录功能,也用不到权限控制(AccessControl),就更不用session存储url了。嗯,应该是这么回事。不用登录操作的话,也就不会涉及到刚开始提到的页面跳转了。
完
相关文章推荐
- html页面jQUery获取url地址以及参数
- php-curl获取接口图片地址,在php拼接img中无法访问,报403错误,在浏览器url中直接可以访问,html页面里img也可以访问
- AS:Flash AS3中获取浏览器信息及URL相关参数(并非swf url地址)
- 用java获取360doc页面上的url地址并在浏览器中自动打开
- minix进程相关学习 未完待续 以及minix源码下载地址
- 微信会员注册开发【带源码】:网页授权,得到code后在当前页面获取openid,js+php实现跨域请求
- 微信小程序实现页面跳转传值以及获取值的方法分析
- 使用RewritePath方法实现【不同路径+任意URL后缀重写到指定页面且URL地址不变】(附源码)_AX
- YII2中常用的页面跳转,以及获取用户信息和登录信息等信息总结
- 切换导航标签实现当前标签颜色改变以及利用js如何准确获取当前页面url网址信息
- 前端工作日常爬坑之——单页面微信开发Jssdk相关,以及jssdk图片直传自己服务器的实现。
- 使用IHttpHandler接口实现【不同路径+任意URL后缀重写到指定页面且URL地址不变】(附源码)_AX
- 基于sina微博官方sdk源码实现的微博授权登录和分享,以及获取信息
- DedeCms获取当前页面URL地址的实现方法
- 在Wordpress的文章页面获取上一页及下一页的链接URL地址,实现通过键盘的前进后退键进行翻页
- 使用IHttpHandler接口实现【不同路径+任意URL后缀重写到指定页面且URL地址不变】(附源码)_AX
- 获取电脑物理地址以及通过IP地址获取当前地理位置(省份)的接口
- Java学习笔记之网络编程基础-通过URL获取HTML页面
- ASP获取当前页面URL地址(带参数)的方法
- 配置拦截器 获取拦截器配置信息 加解密登录信息避免url地址明文显示