我受命为基于Firebase的Android应用程序构建Web界面。我有一些与数据库交互的端点(云函数)。要访问这些端点,我需要使用电子邮件和密码[1]对用户进行身份验证,检索accessToken
[2]并授权使用Authorization: Bearer {accessToken}
标头对端点的每个请求进行授权。
我使用php并竭尽全力想如何在我的应用程序中管理经过身份验证的用户。
我通过php会话中的ajax传输accessToken,以将cURL请求签名到端点。显然,除了使用firebase JS
auth之外,别无其他方法(据我所知[4])。
我的问题是: 是否足以将其保存accessToken
在php会话中,并通过ajax
POST请求将其与每个页面加载进行比较(请参见下面的代码)?在php中,有什么更健壮的策略来解决这个问题?
编辑:一位用户指出,使用带有JWT令牌的经典php会话没有多大意义,我读了有关该主题的文章。那么关于Firebase-
这是要考虑的事情吗? https://firebase.google.com/docs/auth/admin/manage-
cookies
Firebase
Auth为依赖会话cookie的传统网站提供服务器端会话cookie管理。与客户端短暂的ID令牌相比,此解决方案具有多个优点,客户端短暂的ID令牌可能每次需要使用重定向机制来在到期时更新会话cookie:
这是我得到的:
1.登录页面
如Firebase示例中所述[3]
function initApp() {
firebase.auth().onAuthStateChanged(function (user) {
if (user) {
// User is signed in.
// obtain token, getIdToken(false) = no forced refresh
firebase.auth().currentUser.getIdToken(false).then(function (idToken) {
// Send token to your backend via HTTPS
$.ajax({
type: 'POST',
url: '/auth/check',
data: {'token': idToken},
complete: function(data){
// data = {'target' => '/redirect/to/route'}
if(getProperty(data, 'responseJSON.target', false)){
window.location.replace(getProperty(data, 'responseJSON.target'));
}
}
});
// ...
}).catch(function (error) {
console.log(error);
});
} else {
// User Signed out
$.ajax({
type: 'POST',
url: '/auth/logout',
complete: function(data){
// data = {'target' => '/redirect/to/route'}
if(getProperty(data, 'responseJSON.target', false)){
// don't redirect to itself
// logout => /
if(window.location.pathname != getProperty(data, 'responseJSON.target', false)){
window.location.replace(getProperty(data, 'responseJSON.target'));
}
}
}
});
// User is signed out.
}
});
}
window.onload = function () {
initApp();
};
2.一个PHP控制器来处理身份验证请求
public function auth($action)
{
switch($action) {
// auth/logout
case 'logout':
unset($_SESSION);
// some http status header and mime type header
echo json_encode(['target' => '/']); // / => index page
break;
case 'check':
// login.
if(! empty($_POST['token']) && empty($_SESSION['token'])){
// What if I send some bogus data here? The call to the Endpoint later would fail anyway
// But should it get so far?
$_SESSION['token'] = $_POST['token'];
// send a redirect target back to the JS
echo json_encode(['target' => '/dashboard']);
break;
}
if($_POST['token'] == $_SESSION['token']){
// do nothing;
break;
}
break;
}
}
3.主控制器
// pseudo code
class App
{
public function __construct()
{
if($_SESSION['token']){
$client = new \GuzzleHttp\Client();
// $user now holds all custom access rights within the app.
$this->user = $client->request(
'GET',
'https://us-centralx-xyz.cloudfunctions.net/user_endpoint',
['headers' =>
[
'Authorization' => "Bearer {$_SESSION['token']}"
]
]
)->getBody()->getContents();
}else{
$this->user = null;
}
}
public function dashboard(){
if($this->user){
var_dump($this->user);
}else{
unset($_SESSION);
// redirect to '/'
}
}
}
注意:我知道这个sdk https://github.com/kreait/firebase-
php,我在那里读了很多文章,在SO上的文章里也读到很多,但是我很困惑,因为这里有关于完全管理员的讨论。权限等。我实际上仅与基于Firebase的端点进行交互(加上firebase
auth和firestore)。而且我仍然在php 5.6上:-/
谢谢你的时间!
我不得不承认,firebase文档和示例的复杂性以及不同的服务使我非常困惑,以至于我认为只能通过JavaScript进行Web身份验证。错了
至少对于我来说,我只是 使用电子邮件和密码登录 以 检索Json Web令牌(JWT)
,以对Firebase云功能的所有调用进行签名。无需处理奇怪的Ajax请求或通过JavaScript设置令牌cookie,我只需要调用FirebaseAuth REST API
这是使用Fatfreeframework的最小情况:
登录表单
<form action="/auth" method="post">
<input name="email">
<input name="password">
<input type="submit">
</form>
路线
$f3->route('POST /auth', 'App->auth');
控制者
class App
{
function auth()
{
$email = $this->f3->get('POST.email');
$password = $this->f3->get('POST.password');
$apiKey = 'API_KEY'; // see https://firebase.google.com/docs/web/setup
$auth = new Auth($apiKey);
$result = $auth->login($email,$password);
if($result['success']){
$this->f3->set('COOKIE.token',$result['idToken']);
$this->f3->reroute('/dashboard');
}else{
$this->f3->clear('COOKIE.token');
$this->f3->reroute('/');
}
}
}
类
<?php
use GuzzleHttp\Client;
class Auth
{
protected $apiKey;
public function __construct($apiKey){
$this->apiKey = $apiKey;
}
public function login($email,$password)
{
$client = new Client();
// Create a POST request using google api
$key = $this->apiKey;
$responsee = $client->request(
'POST',
'https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=' . $key,
[
'headers' => [
'content-type' => 'application/json',
'Accept' => 'application/json'
],
'body' => json_encode([
'email' => $email,
'password' => $password,
'returnSecureToken' => true
]),
'exceptions' => false
]
);
$body = $responsee->getBody();
$js = json_decode($body);
if (isset($js->error)) {
return [
'success' => false,
'message' => $js->error->message
];
} else {
return [
'success' => true,
'localId' => $js->localId,
'idToken' => $js->idToken,
'email' => $js->email,
'refreshToken' => $js->refreshToken,
'expiresIn' => $js->expiresIn,
];
}
}
}
学分
问题内容: 我正在尝试使用jQuery的功能上传文件,但未获得任何输出。有人请帮我解决这个问题。我不知道此脚本是否正确。我的脚本是: 我还需要帮助,使用jQuery从文件上传字段获取数据。 问题答案: AJAX不支持文件上传。有些插件如ajaxfileupload基本上会创建一个隐藏的表单并动态上传文件。
问题内容: 当前,我正在运行一个查询,该查询将显示“产品”表和与产品相关联的“用户”的所有内容。它打印在桌子上。我想创建一个按钮,显示所有记录。请注意,我只能只查看选定的记录。.我将如何处理? 因此,应该为每个返回的记录显示一个按钮。当我单击此按钮时,将出现另一个窗口,该窗口显示了全部内容(仅针对此记录)以及与之相关的用户。该按钮如何知道与其关联的记录。 问题答案: 这将带您到另一个页面。使用ge
问题内容: 我在通过localhost上的PHP脚本选择数据库时遇到麻烦。 我100%确定数据库名称拼写正确,并且实际上它很好地出现在phpmyAdmin上,并且仅当我尝试通过在本地主机上运行PHP脚本尝试连接到它时,它才会显示以下错误: 我的PHP代码在这里: 我已经阅读了成千上万个论坛,并且我将尽一切努力。但是不知道这里出了什么问题吗? 一件有趣的事情是,如果我在PHP脚本中将数据库名称更改为
问题内容: 这是一个时间表,它的作用是显示前一天的时间表以及谁预定了每个时段(这是针对广播电台的。) 目前,它显示谁按时间顺序预订了每个时段,但是我想说每个结果旁边的时间。查询输出24行(从午夜到23:00),我想说的是每个插槽旁边的(00:00,01:00,02:00,03:00… 21:00,22 :00,依此类推。) 这是我当前的代码: 你能帮我吗? 问题答案: 我认为我们都在努力解决一个非
问题内容: 精通PHP但学习Java的人应该知道的PHP与Java之间的主要区别是什么? 编辑: 我的意思是这些语言的语法上的差异,即它们的数据类型,它们如何处理数组和引用变量等等:) 问题答案: 这不是一个详尽的清单,我是PHP开发人员,前一段时间做过Java之旅,所以做了Caveat Emptor。 Java中的每个变量都必须以数据类型开头。这包括基本类型,例如boolean,int,doub
问题内容: 我在JavaScript中输入了一个绝对URL,并为window.location进行了硬编码。 我不想每次测试应用程序时都必须更改此设置。在PHP中,我可以通过测试$ _SERVER [“ HTTP_HOST”]变量来找出我所在的服务器,然后进行相应的调整来处理此问题。但是,我不太熟悉Java,想知道它是否具有类似的方法?或者,即使JavaScript也有类似的方法? 代码如下: 我
问题内容: 在PHP中构建MVC框架后,我遇到了一个问题,可以使用Java样式泛型轻松解决。抽象的Controller类可能看起来像这样: 在某些情况下,Controller类的子类只能接受Model的子类。例如,ExtendedController应该只将ReOrderableModel接受到addModel方法中,因为它提供了ExtendedController需要访问的reOrder()方法
问题内容: 我一直在尝试使用AES-128 CBC解密字符串,该字符串最初是使用JAVA AES加密加密的。在Java中,使用PKCS7填充。而且我尝试使用类似的PHP代码进行加密和解密。但是我得到了不同的结果。 我的Java代码 以及我正在使用的等效PHP代码。 在Java中 纯文本= 123456 密码文本= tpyxISJ83dqEs3uw8bN / + w == 在PHP中 纯文本=