我的任务是为基于firebase的Android应用构建一个Web界面.
我有一些与数据库交互的端点(云功能).要访问这些端点,我需要使用电子邮件和密码[1]对用户进行身份验证,检索accessToken [2]并使用Authorization:Bearer {accessToken}标头授权对端点的每个请求.
我使用php并努力思考如何在我的应用程序中管理经过身份验证的用户.
我在php会话中通过ajax传输accessToken,以便向端点签署cURL请求.
显然没有其他方法可以使用firebase JS auth(据我所知[4]而言).
我的问题是:是否足以在php会话中保存accessToken并通过ajax POST请求将其与每个页面加载进行比较(参见下面的代码)?
在php中处理这个问题会有什么更强大的策略?
Firebase Auth provides server-side session cookie management for traditional websites that rely on session cookies. This solution has several advantages over client-side short-lived ID tokens, which may require a redirect mechanism each time to update the session cookie on expiration:
这是我得到的:
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控制器来处理auth请求
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云功能的调用.而不是通过JavaScript处理奇怪的Ajax请求或设置令牌cookie,我只需要调用Firebase Auth REST API
以下是使用Fatfreeframework的最小案例:
登录表格
路线
$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('/');
}
}
}
类
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,
];
}
}
}
标签:php,ajax,firebase,firebase-authentication
来源: https://codeday.me/bug/20190627/1303734.html