目前实践一个项目。有些小问题。可能想法错了,还望大家指点一下。 目录结构:
---vue-laravel
|
| ---- client #这是纯的 vue 目录
| ---- server #laravel 放在这里
laravel 提供 api 并且通过 CORS 解决跨域的问题。
目前认证这块是正常的。
但是我想把注册的模块也通过 vue 来实现页面展示, laravel 来存入数据库。但是,我使用 CORS 来提交数据会报 422 的错误。好像应该我没有把 CSRF 值传入的问题。
代码如下: vue 提交注册数据
handleRegisterFormSubmit () {
const postData = {
grant_type: 'client_credentials',
client_id: clientId,
client_secret: clientSecret,
email: this.register.email,
password: this.register.password,
password_confirmation: this.register.password_confirmation,
name: this.register.name,
scope: ''
}
this.$http.post('http://localhost:8000/api/register', postData)
.then(response => {
console.log(response)
})
}
laravel Api 路由:
Route::post('/register',"Auth\RegisterController@register");
请问应该怎么来处理这种没有认证之前的前后端数据交互呢?谢谢
this.$http.post(loginUrl, postData)
.then(response => {
// 设置客户端认证
if (response.status === 200) {
console.log(response)
clientAuth.access_token = response.data.access_token
window.localStorage.setItem('clientAuth', JSON.stringify(clientAuth))
}
// 携带客户端认证信息和要post的数据
this.$http.post('http://127.0.0.1:8000/api/register',
postDataRegister, {headers: getHeaderClient()})
.then(response => {
console.log(response)
})
})
header
export const getHeaderClient = function () {
const tokenData = JSON.parse(window.localStorage.getItem('clientAuth'))
const headers = {
'Accept': 'application/json',
'Authorization': 'Bearer ' + tokenData.access_token,
}
return headers
}
客户端认证成功,但是提交数据就401
经过一下午反复思考,最终还是决绝了。但是如果laravel中register的validator如果出现,比如两个密码不一致或者密码长度小于6,反者就是这个验证过不了就会出现 422 (Unprocessable Entity)的错误。这一块准备在前端这边进行一个判断然后再post请求。
code如下:
methods: {
handleRegisterFormSubmit () {
const postData = {
grant_type: 'client_credentials',
client_id: clientId,
client_secret: clientSecret,
scope: ''
}
const postDataRegister = {
grant_type: 'client_credentials',
client_id: clientId,
client_secret: clientSecret,
email: this.register.email,
password: this.register.password,
password_confirmation: this.register.password_confirmation,
name: this.register.name,
scope: ''
}
const clientAuth = {}
this.$http.post(loginUrl, postData) // 获取客户端认证
.then(response => {
if (response.status === 200) {
console.log(response)
clientAuth.access_token = response.data.access_token
window.localStorage.setItem('clientAuth', JSON.stringify(clientAuth)) // 本地存储认证信息
}
this.$http.post('http://127.0.0.1:8000/api/register',
postDataRegister, {headers: getHeaderClient()})
.then(response => {
console.log(response) // post请求创建
})
})
}
}
一些常量:
export const apiDomain = 'http://localhost:8000/'
export const loginUrl = apiDomain + 'oauth/token'
export const userUrl = apiDomain + 'api/user'
总算解决了。
1
airycanon 2017-02-22 12:41:09 +08:00 1
Laravel 5.4 里面用的是 axios 发请求,原理如下:
把变量传到页面中: ``` <script> window.Laravel = {!! json_encode([ 'csrfToken' => csrf_token(), ]) !!}; </script> ``` 在 axios 的 header 中设置 csrfToken : ```window.axios.defaults.headers.common = { 'X-CSRF-TOKEN': window.Laravel.csrfToken, 'X-Requested-With': 'XMLHttpRequest' }; ``` 用 Vue 的话同理。 |
2
airycanon 2017-02-22 12:51:36 +08:00
不好意思,没看清是前后端分离,这样的话我只知道设置 CSRF 中间件的 $except ,可以排除掉某些路由,或者直接在 Http\Kernel.php 中禁用 CSRF 中间件了。
|
3
branchzero 2017-02-22 12:57:37 +08:00 1
你确定走了 api 的 middleware 了么,如果走 api 的 middleware 的话默认是不会启用 csrf check 的
|
4
linkbg OP @branchzero 谢谢。但是新的问题是 401 但是我明明已经取得客户端授权了。请问这个怎么解决呢?我将新的情况补充在问题上。
|
5
ydxred 2017-02-22 14:32:40 +08:00
分离不是应该写在视图里面吗?
|
7
coooooooode 2017-02-22 15:49:48 +08:00
和我想的一样,前端就只做前端的事,让 vue 控制数据与 api 调用。 支持!
|
8
jellybool 2017-02-22 16:11:59 +08:00
我觉得你阔以看看这个
|
9
jellybool 2017-02-22 16:12:37 +08:00 1
|
10
benbenlang 2017-02-22 18:15:56 +08:00
@jellybool 你的视频要付费啊,,,
|
11
jellybool 2017-02-22 19:03:48 +08:00
@benbenlang 是的
|
15
sobigfish 2017-02-22 21:31:39 +08:00
|
16
linoder 2017-02-22 22:01:43 +08:00
都分离了 csrf 还有用么?
|
17
linkbg OP scrf 没有用了。是传入 access_token 。
|
19
yangqi 2017-02-22 22:45:00 +08:00
都前后端分离了,直接把 csrf 的 middleware 关掉就行了
|
20
crossmaya 2017-02-23 04:04:33 +08:00
一看就是 auth 中间件的问题!
|
21
chaegumi 2017-02-23 08:51:40 +08:00
为什么没人说
client_id: clientId, client_secret: clientSecret, 同时存在在 js 代码中,是否有问题。限制该 client_id 只能使用特定的 grant_type ? |