Laravel Passport 401 Unauthorized Error using Apache and Vue - apache

i am trying to connect a generate a laravel user API using vue and laravel passport but i keep getting an authorization error in my headers . This ismy code
<script>
import Hello from './components/Hello'
export default {
name: 'app',
components: {
Hello
},
created () {
const postData = {
grant_type: 'password',
client_id: 2,
client_secret: 'sXdg5nOO4UU2muiHaQnTq4hDQjyj17Kd9AeKuNEx',
username: 'robertrutenge#gmail.com',
password: 'password',
scope: ''
}
this.$http.post('http://localhost:8000/oauth/token', postData)
.then(response => {
console.log(response)
const header = {
'Accept': 'application/json',
'Authorization': ~'Bearer ' + response.body.access_token
}
this.$http.get('http://localhost:8000/api/user', {headers: header})
.then(response => {
console.log(response)
})
})
}
}
</script>
I have done a research and most answers suggest modifying apache config file or .htaccess file but that also does not seem to work on my end . Any help will be appreciated :-)

i think if your vue app and laravel app is combine, then you can use your api without any authorization header you just need to send X-CSRF-TOKEN and send that token with each request no need to send authorization check here
https://laravel.com/docs/5.3/passport#consuming-your-api-with-javascript

this is not problem on in vue.js or larvel. i moved my l Laravel API from Apache to nginx then working fine. i updated my middleware handler like this. then working fine on Apache server
$origin = $request->server()['HTTP_ORIGIN'];
if(in_array($origin, $url)){
header('Access-Control-Allow-Origin: '. $origin);
header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, X-Csrf-Token');
}

resolve (2)
go to
AuthServiceProvider.php
keypoint:set expiration of token
Passport::tokensExpireIn(Carbon::now()->addDays(1));
You must to set token expiration
cant be infinite

Related

No Set-Cookie header on Axios

I am using a Symfony API backend and want to authenticate by REST call via Axios inside a Vue App.
The authentication works fine when using POSTMAN. It stores a session cookie and resends it on subsequent requests.
However, when I use Axios it won't give me the Set-Cookie header.
What I tried so far:
Adjusted CORS settings on Symfony backend (no CORS errors - all routes working)
Set { withCredentials: true } as config parameter on Axios post request.
Symfony EventSubsriber for injecting CORS headers:
public function onKernelResponse(ResponseEvent $event)
{
$response = $event->getResponse();
$response->headers->set('Access-Control-Allow-Methods', '*');
$response->headers->set('Access-Control-Allow-Headers', [ 'Content-Type', 'Set-Cookie' ]);
$response->headers->set('Access-Control-Allow-Origin', 'http://localhost:3000');
$response->headers->set('Access-Control-Allow-Credentials', 'true');
$response->setStatusCode(200);
}
Note that this is for local testing only.
Axios Request:
login(user, pw) {
return axios.post(cfg.apiUrl + '/api/login', {
username: user,
password: pw
},
{ withCredentials: true }
);
}
Follow up request:
test() {
return axios.get(cfg.apiUrl + '/api/test');
}
Could someone point out what I am still missing? Why do I get the header on POSTMAN, but not on Axios?
The solution is to also add the { withCredentials: true } in further requests. As it seems, it is not possible to read the Set-Cookie header via Axios, as #jub0bs pointed out.
The correct code for a follow-up request looks like:
test() {
return axios.get(cfg.apiUrl + '/api/test', { withCredentials: true });
}

Problems to get a refresh token using vue, nuxt and keycloak

I'm doing a project with vue, nuxt and keycloak as server for token, axios as http client and #nuxtjs/auth-next module for keycloak access.
I'm using a public client so I don't have a secret key which is the most recommended.
The part of getting the token and talking to the backend is working.
But as it is a public client it has no refresh token.
Searching the internet, a recommendation would be to post from time to time to the keycloak /token endpoint, passing the current token, to fetch a new token.
To perform this post, it doesn't work to pass json, having to pass application/x-www-form-urlencoded.
But it generates an error saying that the parameter was not passed.
On the internet they recommended passing it as url string, but then it generates an error on the keycloak server, as a parameter that is too long, because of the current token that is passed.
Below is the code used to try to fetch a new token.
This code is being called on a test-only button.
If anyone can help, I appreciate it.
const token = this.$auth.strategy.token.get()
const header = {
"Content-Type": "application/x-www-form-urlencoded"
}
const body = {
grant_type: "authorization_code",
client_id: "projeto-ui",
code: token
}
this.$axios ( {
url: process.env.tokenUrl,
method: 'post',
data: body,
headers: header
} )
.then( (res) => {
console.log(res);
})
.catch((error) => {
console.log(error);
} );
Good afternoon people.
Below is the solution to the problem:
On the keycloak server:
it was necessary to put false the part of the implicit flow.
it was necessary to add web-origins: http://localhost:3000, to allow CORS origins.
In nuxt.config.js it was necessary to modify the configuration, as below:
auth: {
strategies: {
keycloak: {
scheme: 'oauth2',
...
responseType: 'code',
grantType: 'authorization_code',
codeChallengeMethod: 'S256'
}
}
}

How to pass header in axios request?

I'm trying to implement Laravel Cashier and Stripe Subscriptions into my Laravel and Vue js SPA. I'm using Laravel Passport and jwt for authentication. I found an article online on how do this.
Whenever I click "Pay" button I get 401 Unauthorized error and when I click on URL in Network tab it gives error unauthenticated.
I think the issue is because I'm not passing the 'Authorization': 'Bearer '+auth.getAccessToken() in the headers when trying to access those routes.
Here is the method from the article:
loadIntent(){
axios.get('/api/v1/user/setup-intent')
.then( function( response ){
this.intentToken = response.data;
}.bind(this));
},
Here is what I tried, but this doesn't seem to be working:
loadIntent(){
const headers = {
'Authorization': 'Bearer '+auth.getAccessToken(),
};
axios.get('/api/v1/user/setup-intent', {
headers: headers
})
.then( function( response ){
this.intentToken = response.data;
}.bind(this));
},
Any idea what the issue is?

vue-resource interceptor for auth headers

I am trying to set up a Vuejs fronted application (vue-cli webpack template) to sit on top of my Laravel API.
I am able to get a successful response from the API with vue-resource by providing the correct auth token, for example:
methods: {
getUser () {
this.$http.get('http://localhost:8000/api/user',
{
headers: {
'Authorization': 'Bearer eyJ0e.....etc',
'Accept': 'application/json'
}
}).then((response) => {
this.name = response.data.name
});
},
However, I am now trying to set up interceptors so that the user's auth token will automatically be added for each request.
Based on the vue-resource readme I am trying this in my main.js:
Vue.use(VueResource)
Vue.http.interceptors.push((request, next) => {
request.headers['Authorization'] = 'Bearer eyJ0e.....etc'
request.headers['Accept'] = 'application/json'
next()
})
And then back in my component I now just have:
this.$http.get('http://localhost:8000/api/user').then((response) => {
this.name = response.data.name
});
Problem:
When I specify the headers in the get itself, I get a successful response, but when I pass them through the interceptor I get back a 401 Unauthorized from the server. How can I fix this to respond successfully while using the interceptor?
Edit:
When I use dev-tools to view the outgoing requests I see the following behavior:
When making the request by supplying the headers to $http.get, I make a successful OPTIONS request and then a successful GET request with the Authentication header being supplied to the GET request.
However, when I remove the headers from the $http.get directly and move them to the interceptor, I only make a GET request and the GET does not contain the Authentication header, thus it comes back as a 401 Unauthorized.
It turns out my problem was the syntax for which I was setting the headers in the interceptor.
It should be like this:
Vue.use(VueResource)
Vue.http.interceptors.push((request, next) => {
request.headers.set('Authorization', 'Bearer eyJ0e.....etc')
request.headers.set('Accept', 'application/json')
next()
})
While I was doing this:
Vue.use(VueResource)
Vue.http.interceptors.push((request, next) => {
request.headers['Authorization'] = 'Bearer eyJ0e.....etc'
request.headers['Accept'] = 'application/json'
next()
})
Add this option:
Vue.http.options.credentials = true;
And use the interceptors for global way:
Vue.http.interceptors.push(function(request, next) {
request.headers['Authorization'] = 'Basic abc' //Base64
request.headers['Accept'] = 'application/json'
next()
});

simple-auth-token JWT authorization not setting Authorization header

I'm trying to setup a simple Ember.js app to talk with a custom API server, with JWT authentication.
I can login at the API server and obtain a JWT token, but then no Authorization header is set in subsequent calls to the API server.
My login controller is:
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
authenticate: function() {
var credentials = this.getProperties('identification', 'password'),
authenticator = 'simple-auth-authenticator:jwt';
this.get('session').authenticate(authenticator, credentials).then(function() {
// authentication was successful
console.log('OK');
}, function(err) {
// authentication failed
console.log('FAIL ' + JSON.stringify(err));
});
},
logOut: function() {
this.get('session').invalidate();
}
}
});
I can successfully login and obtain a token. My login route:
import Ember from 'ember';
export default Ember.Route.extend({
actions: {
sessionAuthenticationFailed: function(error) {
console.log('Login error: ' + error.ErrorDesc);
this.controllerFor('login').set('loginErrorMessage', error.ErrorDesc);
this.controllerFor('login').set('ErrorMoreInfo', error.MoreInfo);
},
sessionAuthenticationSucceeded: function() {
console.log('Session authenticated: ' + this.get('session').content.secure.token);
// redirect to last route requested, or to default route
var attemptedTransition = this.get('session').get('attemptedTransition');
if (attemptedTransition) {
attemptedTransition.retry();
this.get('session').set('attemptedTransition', null);
} else {
this.transitionTo('index');
}
}
}
});
...shows me the token is properly acquired, and correctly redirects me to my protected routes (e.g. index). Since then, if I try to get any data from the API server, it does not receive any "Authorization: Bearer [token]" header at all.
My environment configuration:
ENV['simple-auth'] = {
authorizer: 'simple-auth-authorizer:token'
};
ENV['simple-auth-token'] = {
refreshAccessTokens: true,
timeFactor: 1000,
refreshLeeway: 300, // Refresh the token 5 minutes (300s) before it expires.
serverTokenEndpoint: 'https://localhost:8000/login',
crossOriginWhitelist:[
'http://localhost:4200',
'https://localhost:8000'
],
identificationField: 'user',
passwordField: 'password',
tokenPropertyName: 'token',
authorizationPrefix: 'Bearer ',
authorizationHeaderName: 'Authorization',
// headers: {},
};
I also tried manually setting the header by calling jqXHR.setRequestHeader overriding the authorize function in my login route, but with no success:
authorize: function(jqXHR, requestOptions) {
var auth= "Bearer " + this.get('session').content.secure.Token;
console.log('Add authorization header ' + auth);
console.log( JSON.stringify(requestOptions));
jqXHR.setRequestHeader("Authorization", auth);
}
Can anybody tell what I'm missing? Shouldn't simple-auth-token take care of adding the header automatically?
Thanks for any help,
al.
I had the same issue, with a REST adapter making calls on a different port.
Solved adding
ENV['simple-auth'] = {
crossOriginWhitelist: ['*']
}
Xabi's answer is working for me. But I didn't find it intuitive.
"Authorized requests" comply to a restrictive CORS policy : the authorization is not added in case of CORS issue.
In the docs :
Ember Simple Auth will never authorize requests going to a different origin than the one the Ember.js application was loaded from.
But requests that don't need an authorizer (with no 'Authorization' header in case of JWT) are allowed and working fine.