I was just suffering this issue sending data from a Laravel API to a Vue SPA, via the "login using oauth" callback blade template.
It took me some time to figure out how exactly to fix the payload. I found the answer in this question thanks to Amit Gupta's answer.
Here is the payload exiting Laravel, for context:
return view('oauth/callback', [
'user' => $user,
]);
Then, in callback.blade.php
, I have this code:
<html>
<head>
<meta charset="utf-8">
<title>{{ config('app.name') }}</title>
<script>
window.opener.postMessage(
{
user: {!! $user !!},
},
"{{ url('/') }}"
);
window.close();
</script>
</head>
<body>
</body>
</html>
I had to change this:
user: "{{ $user }}",
to this:
user: {!! $user !!},
Before the fix, I was getting a stringified object interpolated into the string, so I was plagued with SyntaxError: Unexpected token o in JSON at position 1
errors, because the {
and }
characters weren't encased in double-quotes.
Here is my JavaScript that receives the payload:
onMessage(e) {
const hasUser = (e.data.user && (Object.keys(e.data.user).length > 0));
if ((e.origin !== window.origin) || !hasUser) {
return undefined;
}
console.log('user payload', e.data.user);
console.log('type', typeof e.data.user);
if (this.hasIntendedUrl) {
return this.$router.push(this.$store.getters['auth/intendedUrl'])
.then(() => this.$store.dispatch('auth/clearIntendedUrl'))
.catch(() => {});
}
return this.$router.push({ name: 'home' }).catch(() => {});
},
You can see I didn't require to JSON.parse()
because typeof e.data.user
is object
.
Sorry for the long answer here, but I wanted to show a fully-qualified solution. To me this is simply a type-casting issue based around first JSON stringifying the payload, and then JSON parsing it. This implies that Laravel should focus on preparing a transport-safe version of the object, and that JavaScript should focus on transforming it back to an Object.
It is always a tricky slope to mix PHP and JS in the same file. As you can see in my example, those innocuous "
wrapping "{{ $user }}"
was JavaScript code being instructed to put the object into a string, and that is something that cannot be JSON.parse()
'd.