Laravel Vue SPA - 代理 Token
打赏作者

Laravel Vue SPA - 代理 Token

Laravel Vue 开发 SPA 应用 >> Laravel Vue SPA - 代理 Token 视频发布于 2017-10-12

在上一个视频我们实现 login 的时候,直接将敏感的 secret 信息写到了 js 代码当中,这是极其不推荐的做法。然后本节视频主要着重引入一层 Proxy 代理,将敏感的信息直接保存到后端,但在这基础之上,我们的 token 分发和校验还是成功的。
phpnodebug

站长 什么时候能出一期laravel后台权限类的视频吗

人生就是挖坑埋自己
message: "curl_setopt_array(): Unable to create temporary file.", exception: "ErrorException",…}
exception
:
"ErrorException"
file
:
"D:\codeing\VueSPA\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php"
line
:
57
message
:
"curl_setopt_array(): Unable to create temporary file."
trace
:
[{function: "handleError", class: "Illuminate\Foundation\Bootstrap\HandleExceptions", type: "->"},…]    Error: Request failed with status code 500
    at createError (app.js:1330)
    at settle (app.js:34107)
    at XMLHttpRequest.handleLoad (app.js:1204)

这个错误是什么意思,站长?

JellyBool 回复 人生就是挖坑埋自己

这种感觉就是 windows 环境的问题吧:https://github.com/guzzle/guzzle/issues/83

zark

后端响应附带的 cookie 的过期时间单位貌似是分钟哦,864000 相当于 600 天了,看视频的时候,cookie 显示过期时间也是 600 天!

JellyBool 回复 zark

好像是这样的诶。我后面说明一下。。。

dppppp

大大 我想问请教下
cookie('refresh_token',$refresh_token,14400);

return response()->json([
            'expires_in'=>$token->expires_in,
            'access_token'=>$token->access_token,
            'refresh_token'=>$token->refresh_token
        ])->cookie('refresh_token',$token->refresh_token);

两种写cookie的方法,我测试了一下下面一种是写进了响应的 header中,并且在cookie中有数据,上面一种为什么存不了呢?

JellyBool 回复 dppppp

cookie(‘refresh_token’,$refresh_token,14400); 这种方式设置完毕之后,你直接 cookie取值一下试试

dppppp 回复 JellyBool

我是试过了 发现这样取不到值,所以才想请教一下,为什么这样取不到呢?

JellyBool 回复 dppppp

直接 Cookie::get 也取不到?还是没在 header

dppppp 回复 JellyBool

抱歉,没有把问题交代清楚,就是用老师您的办法是可以取到值的,并且也在header里面可以看到。
我想问的是

  • 直接用cookie('refresh_token',$refresh_token,14400);这样的方法去存cookie貌似取不到
  • 顺便问下,写api的时候,如果跟安卓,ios对接,传统的session,cookie是不能用的是吧?原因是如何的呢?
JellyBool 回复 dppppp

因为 http 协议是无状态的啊。

这样的方法去存cookie貌似取不到

取不到是哪种方式都取不到么?

waicmy 回复 dppppp

可以返回的时候一起返回给前端.前端去存.

yanerwei

Laravel 5.4 调试后,发现这段代码不执行,请求状态一直 pending
return $this->proxy->proxy(‘password’, [
‘username’=>request(‘email’),
‘password’=>request(‘password’),
‘scope’=>’’
]);

JellyBool 回复 yanerwei

有没有可能是 apacha 或者 nginx 的问题。

EagleKing 回复 yanerwei

我也是,怎么解决的啊

xshaitt 回复 yanerwei

同问,怎么解决

Arun 回复 yanerwei

只要断开网络就可以,连上网络就不行

jasester

在登录的时候,检测是否激活的时候,我这里出现这种错误,
passport
这是什么问题啊?
这是代码

dd(auth('api')->attempt(['username' => $username, 'password' => \request('password')]));
            $request =  $this->proxy->proxy('password', [
                'username' => $request->get('username'),
                'password' => $request->get('password'),
                'scope' => ''
            ]);
            return $request;

这是auth.php中的guards代码

'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'passport',
            'provider' => 'admins',
        ]
    ],
'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],
        'admins' => [
            'driver' => 'eloquent',
            'model' => App\Models\Admins::class,
        ]
        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],
JellyBool 回复 jasester

auth('api') 改成 auth()

jasester 回复 JellyBool

其实是两张表,一个admins,一个users,换成auth() 他走的是users这张表,我想要认证admins这张表,不知道描述的清楚吗?

kwen8 回复 jasester

其实是driver为passport的话guard(‘api’)是没有attempt这个方法的,所以其实你可以在新增一个guards
’admin’ => [
‘driver’ => ‘session’,
‘provider’ => ‘admins’
]
另外我也在做多表登录,能请教一下是passport那边是怎么处理的呢

qq822140

proxy方法中
$response = $this->http->post(‘http://127.0.0.1:8000/oauth/token’,[
‘form_params’ => $data
]);

1、这里url如果用127.0.0.1:8000的话,请求一次服服务器会一直没响应,也不报错,再次刷新页面也没有响应,请求方式改为php的curl也一样,
2、但是单独开一个php文件(不在laravel框架中)又可以得正确的得到响应例如:
url="http://127.0.0.1:8000/oauth/token";url = "http://127.0.0.1:8000/oauth/token"; post_data = array (balabala);//post数据
ch=curlinit();curlsetopt(ch = curl_init(); curl_setopt(ch, CURLOPT_URL, url);curlsetopt(url); curl_setopt(ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt(ch,CURLOPTPOST,1);curlsetopt(ch, CURLOPT_POST, 1); curl_setopt(ch, CURLOPT_POSTFIELDS, postdata);post_data); output = curl_exec(ch);curlclose(ch); curl_close(ch);
print_r($output);

3、但是把项目扔到apache中url用域名又是正常的,为什么?

JellyBool 回复 qq822140

127.0.0.1:8000 是怎么启动?有没可能是同时占用的问题

qq822140 回复 JellyBool

就是php artisan serve启动的,没有其他的占用啊

JellyBool 回复 qq822140

就是说这种启动是不是因为PHP内置服务器,不能同时对付两个请求?两个请求都走 127.0.0.1:8000

qq822140 回复 JellyBool

恩,今天又试了一下apache下的不配置域名用localhost也可以正常访问。
就是php artisan serve这种方式proxy方法中请求自己,服务器就再也没反应了。

blaze0207 回复 JellyBool

我也有此問題,我是用 php artisan serve 啟動 server 的,也是在輸入完帳號密碼送出後就一直 pending,
請問這部分要怎麼處理呢?

saloou

老师帮我看看 我遇到的这个问题,是怎么回事?
执行到这里:

  $response = $this->http->post('http://yshwx.dev/oauth/token', [
            'form_params' => $data
        ]);

就会报错:

 POST http://yshwx.dev/api/login 500 (Internal Server Error)
{message: "Client error: `POST http://yshwx.dev/post/oauth/to…a http-equiv="X-UA-Compatible" co (truncated...)↵", exception: "GuzzleHttp\Exception\ClientException", file: "/Users/saloou/sites/yshwx/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php", line: 113, trace: Array(56)}
exception:"GuzzleHttp\Exception\ClientException"
file:"/Users/saloou/sites/yshwx/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php"
line:113
message:"Client error: `POST http://yshwx.dev/post/oauth/token` resulted in a `419 unknown status` response:↵<!DOCTYPE html>↵<html lang="en">↵    <head>↵        <meta charset="utf-8">↵        <meta http-equiv="X-UA-Compatible" co (truncated...)↵"
JellyBool 回复 saloou

这样我看不出来

walkerpan

执行代理后出现
{message: “Call to a member function post() on null”,…}
exception:"Symfony\Component\Debug\Exception\FatalThrowableError"
file:"C:\laragon\www\api\app\Http\Proxy\TokenProxy.php"
line:34
message:"Call to a member function post() on null"
代码如下:
public function proxy($grantType,array $data=[])
{
data=arraymerge(data=array_merge(data,[
‘client_id’ =>env(‘PASSPORT_CLIENT_ID’),
‘client_secret’ =>env(‘PASSPORT_CLIENT_SECRET’),
‘grant_type’ =>$grantType,
]);
response=response =this->http->post(’/oauth/token’,[ // 这是提示的第 34行代码
’form_params’ => $data
]);

    $token =json_encode((string) $response->getBody(),true);

    return $response()->js([
        'token'      => $token['access_token'],
        'expires_in' => $token['expires_in']
    ])->cookie('refreshToken',$token['refreshToken'],1296000,null,null,false,true);

}
JellyBool 回复 walkerpan

你有注入 this->http 么?

public function __construct(\GuzzleHttp\Client $http)
    {
        $this->http = $http;
    }
Ruanjun
$data = array_merge($data, [
            'client_id'     => env('PASSPORT_CLIENT_ID'),
            'client_secret' => env('PASSPORT_CLIENT_SECRET'),
            'grant_type'    => $grantType
        ]);

        return $data;
        $res = $this->http->post('http://spavue.cn/oauth/token', [
            'form_params' => $data
        ]);

这里的data数据中env获取的数据一直是空的null,然后他就报错了,提示缺少参数

JellyBool 回复 Ruanjun

你正确配置了 PASSPORT_CLIENT_ID 和 PASSPORT_CLIENT_SECRET 么?

是怎么配置的?用的什么环境?

Ruanjun 回复 JellyBool

配置是正确的,我用php artisan config:clear 后又可以了

JellyBool 回复 Ruanjun

那应该是缓存了,没有取到值

thinktoPHP

PASSPORT

coolyon

求教:
Client error: POST http://www.lec.cn/oauth/token resulted in a 400 Bad Request response:↵{“error”:“invalid_request”,“message”:"The request is missing a required parameter, includes an invalid parameter value

JellyBool 回复 coolyon

请求参数缺少了!

blaze0207

@JellyBool

我現在做法是在本地用 Nginx 去指到 vue-spa 目錄,http://localhost:8084,這邊沒有問題,
然後我在去本地 vue-spa 目錄下使用 php artisan serve 來啟動,
然後我先用 Postman 打 Api http://localhost:8000/oauth/token 也有正確拿得到 token,
但是當我用網頁 http://localhost:8084/login 這邊輸入帳號密碼後登入,就會有以下錯誤:

exception:"GuzzleHttp\Exception\ClientException"

file:"/Users/hahn/Practice/vue-spa/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php"

line:113

message:"Client error: `POST http://localhost:8000/oauth/token` resulted in a `400 Bad Request` response:{"error":"unsupported_grant_type","message":"The authorization grant type is not supported by the authorization server." (truncated...)"

請問我問題出在哪呢?
下面是我 proxy function 的 code

public function proxy($grant_type, $data = [])
    {
        $data = array_merge($data, [
          'client_id' => env('PASSPORT_Client_ID'),
          'client_secret' => env('PASSPORT_Client_Secret'),
          'grant_type' => $grant_type,
        ]);

        $response = $this->http->post('http://localhost:8000/oauth/token', ['form-params' => $data]);
        .......
    }
JellyBool 回复 blaze0207
['form-params' => $data]

改成:

['form_params' => $data]
blaze0207 回复 JellyBool

@感謝 JellyBool
真的改成這樣就可以了!!!
原來我又犯了低級錯誤…真是難找!

Yhbin

请问一下JellyBool,最早我的域名是sandbox.ddd:8080,但是curl 报错误6 提示不能解析sandbox.ddd 后来我更改域名为sandbox。然后代码也更改了
$response = $this->http->post(‘http://sandbox:8080/vue-spa/public/oauth/token’, [
‘form_params’ => $data
]);
请求返回结果是404,但是相同的url地址用postman能请求到数据。
我测试把地址把post请求地址换成"http://sandbox:8080" 这个时候不会报错误,当然这个时候返回的expired_in和token都是null。我现在的问题就是填写的地址为 http://sandbox:8080/vue-spa/public/oauth/token这个后, 将得到resulted in a `404 Not Found。 请问这是什么什么原因产生的呢,有什么办法可以解决这个问题,我已经被这个问题困扰3、4天了,谢谢。

JellyBool 回复 Yhbin

/vue-spa/public/oauth/token 不需要 public 吧?你的 nginx 重写没配置好吧

liujun

proxy里面的返回cookie的httponly好像是默认的,后面的null,false等都不要写吧

bs2827883

{message: “The given data was invalid.”, errors: {email: [“The email field is required.”]}
errors:{email: [“The email field is required.”]}message:"The given data was invalid."
POST http://www.eidetika-admin.com/api/login 422 (Unprocessable Entity)

public function login()
{
$this->validateLogin(request());
return $this->proxy->proxy(‘password’,[
‘username’=>request(‘username’),
‘password’=>request(‘password’),
‘scope’=>’’,
]);
}
username我并没有像老师那样取的是email,因为我vue用的也是username,请问是什么原因呢,我一直跟着视频走

smile1line

这样请求在服务器上有个问题,会报401 的错误,Client error: POST http://***/oauth/token resulted in a 401 Unauthorized response:\n
{“error”:“invalid_credentials”,“message”:“The user credentials were incorrect.”}\n

然后我搜索了一下,有个好像是帖子说,好像这个oauth 认证和请求不能再同一个域名下
https://laravel-china.org/articles/6404/laravel-passport-learning-finishing

JellyBool 回复 smile1line

这个信息来看,我觉得是你的邮箱和密码不对咯。或者是你的 key 和 secret 没对

DevTTL

老师的多行编辑快捷键是什么啊

JellyBool 回复 DevTTL

我直接设置的是 command + d 。

你最好看看 phpstorm 的系列

q530004000 回复 JellyBool

command + g 吧. command + d 是 复制选中的代码块并粘贴在下面.

1isten

即便是返回的Credential not match,在cookie中仍能看到refreshToken的信息,请问这是正常的吗?

lxxinxi

功能已正常,功能已正常

EdisonK

我用valet,打开首页怎么是“加载数据”,不知道怎么办了

kuoyeh2019

不是知道是不是版本原因。获取不到env 变量值,郁闷了一个晚上加一个上午时间