SoundCloud API 401 error in Codeigniter - codeigniter

I'm trying to get Soundcloud to return a track ID, but can't get it to work. Documentation here (PHP tab): https://developers.soundcloud.com/docs/api/guide#errors
I've triple checked my credentials from soundcloud that I'm adding as args.
Function in my controller:
function formprocessor()
{
require_once (APPPATH.'third_party/Services/Soundcloud.php');
// create a client object with your app credentials
$client = new Services_Soundcloud('my client id', 'my client secret', 'http://127.0.0.1:8888/index.php/welcome/');
try {
$me = json_decode($client->get('me'), true);
}
catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) {
exit($e->getMessage());
}
}
What would cause this to fail? I keep getting a 401
Here's a reference to the API: https://developers.soundcloud.com/docs/api/reference

you need to authenticate by sending the user (even if thats you) to "authorizeurl":
$authURL = $client->getAuthorizeUrl();
then set the access token with:
$accessToken = $client->accessToken($_GET['code']);
$client->setAccessToken($_SESSION['token']); //if you saved token in a session
Then you should at least be able to "get me" this part is working for me however i cannot access things such as /me/tracks/ or /me/followings/ at the moment.

Related

Can not get laravel cookie laravel_token while consuming own API

Cookie is avaiable in browser but can not get it even can not check if it exists .
working on laravel and vuejs app where I am using passport for authentication.
I am consuming own api with vuejs so I have added CreateFreshApiToken middleware in kernel.php
vuejs is creating and sending laravel_token cookie successfully but I can not read it using vuejs or javascript.
since I can not check if cookie is available or not I can not check if user is logged in or not.
How I will tell vuejs that user is logged in and take to intended route ?
For now I am saving access_token in localStorage and sending it with each request but I am looking for a solution which can help to use laravel builtin laravel_token cookie to authenticate and authorize the users.
More Details
If i run this command in console then I get response
document.cookie.match('XSRF-TOKEN')
But
document.cookie.match('laravel_token')
returns null
I think the tick icon in the shown image at top is sign of making it private or something that makes it inaccessible.
Update
I found something from internet
But I still want to know how I can tell vuejs app that user is logged in or not ??
Update 2
For now I am sending access_token in header manually from vuejs and it is working fine.
if(localStorage.getItem('laravel_token') !== 'undefined' && !! localStorage.getItem('laravel_token') == true){
window.axios.defaults.headers.common['Authorization'] = 'Bearer '+ localStorage.getItem('laravel_token')
}
A little work around will be for you to implement the authenticated method in your LoginController, and return a json success code. You can then receive this code and store.
public function authenticated(Request $request, $user)
{
// return redirect()->intended($this->redirectPath());
return json_encode(['authenticated' => true]);
}
Using axios...
axios.post('/login', {
email: user.username,
password: user.password
}).then(response => {
.then(response => {
console.log(response)
//response.data.authenticated will return true if user has been authenticated
})
}).catch(err => {
console.log(err)
})

Laravel socialite 400 Bad Request response

i have created a laravel socialte setup .and it was working before perfectly now its showing error(below).
1)i have changed client_secret
2)created a new oauth credentials
still not working
public function redirectToGoogle()
{
return Socialite::driver('google')->redirect();
}
public function handleGoogleCallback()
{
$user = Socialite::driver('google')->stateless()->user();
$user->getId(); // 1472352
$user->getNickname(); // "overtrue"
$name= $user->getName(); // "安正超"
$emailid= $user->getEmail();
$pic= $user->getAvatar(); // "anzhengchao#gmail.com"
return->redirect('welcome');
}
i have created env file with client_secret and client id
"""
Client error: `POST https://accounts.google.com/o/oauth2/token` resulted in a `400 Bad Request` response:\n
{\n
"error" : "invalid_grant",\n
"error_description" : "Code was already redeemed."\n
}\n
"""
When Google return the Authentication Code code to your Socialite, it can only be used to exchange to Access Token once. Doing more than once will result in the error Code was already redeemed.
The flow should be:
User click the login button on your website
You redirect user to Google and Google is asking user to login/grant you access
If successful, Google redirects back to you with a one-time-use Authentication Code?code=.....
Socialite use the ?code and exchange it with Google to get user's Access Token. This can only be done once per flow.
You can now request user details using the access token requested in step 4.
Read similar answer: https://stackoverflow.com/a/32710034/534862

How to construct a private sever-to-client-side API? Laravel Passport?

I'm not sure if I'm using the correct method for my problem.
I would like to get Infos via Axios. For example: calling: /api/user with Axios gets me the user, but I don't want to see the information when I go on domain.test/api/user.
I even want to use API calls to get Results of Functions even if the User is a Guest.
I installed everything there is on the Laravel Documentation for API, but still I'm not sure how the user gets the Token.
So if I call:
axios.get('/api/user')
.then(response => {
console.log(response.data);
});
I get from the network tab {"message":"Unauthenticated."}. (I didn't forget to set: ...Middleware\CreateFreshApiToken::class and everything there is).
I think my problem is that I didn't register the User correctly. I got my two keys what should I do with it?
And then it's weird, reading the blog https://laravelcode.com/post/laravel-passport-create-rest-api-with-authentication, they use
$success['token'] = $user->createToken('MyApp')->accessToken;
But I don't get it. Where do I save it? I'm super confused, because every blog about shows Laravel Passport completely differently.
Or am I doing it wrong?
Passport is an OAuth2 server implementation which offers several different authorization strategies. While it is certainly possible to use Passport for authentication, it's primary purpose is authorization. This is done via token scopes. The type of token you choose to issue depends on your intended purpose with the API and whom your intended target is to be consuming your api.
Let's start with the following:
$success['token'] = $user->createToken('MyApp')->accessToken;
Here they are creating Personal Access Tokens. This is the simplest means of consuming your api, since clients are able to create the token themselves as needed and are long lived.
The Password Grant strategy is also a good option. A common approach when using this strategy is proxying authentications to Passport internally and merging the client id and secret into the request in a middleware.
public function handle($request, $next) {
return $next(tap($request, function($request) {
$request->merge([
'client_id' => config('services.passport.client.id'),
'client_secret' => config('services.passport.client.secret')
]);
// do any other pre-request work needed here
}));
}
Setup
To get started with Passport, run the command:
php artisan passport:install
This will create the encryption keys as well as a personal access and password grant client types, which will be stored in your database in the oauth_clients table.
Guard and Middleware
API routes need to be using the api guard, done by setting auth:api middleware on the route group(s) or Controller constructor.
// using via constructor
public function __construct()
{
$this->middleware('auth:api');
}
// via a route group
Route::group(['middleware' => ['auth:api'], function() {
// your api routes
});
Passport Routes
Your user model needs to be using the trait HasApiTokens and within the AuthServiceProvider call Passport::routes() in the boot method.
public function boot()
{
$this->registerPolicies();
Passport::routes();
// this is also an ideal time to set some token expiration values
Passport::tokensExpireIn(now()->addDays(15));
Passport::refreshTokensExpireIn(now()->addDays(30));
}
To use the personal access token strategy for authentication, you need to create your own login and logout routes instead of using the builtin Laravel auth mechanisms.
Referring to the tutorial in your question, they have defined the following routes:
Route::post('login', 'API\PassportController#login');
Route::post('register', 'API\PassportController#register');
and the login method implemented as:
public function login(){
if(Auth::attempt(['email' => request('email'), 'password' => request('password')])){
$user = Auth::user();
$success['token'] = $user->createToken('MyApp')->accessToken;
return response()->json(['success' => $success], $this->successStatus);
}
else{
return response()->json(['error'=>'Unauthorised'], 401);
}
}
This is expecting a ajax request with an email and password to be posted to login and if successful it responds with an access token.
Storing/Using the Token
This token must be stored client side, either in a cookie or local storage, for example, and then added to every request from the client there after. You'll add the token to the Authorization header in client requests.
// Use a response interceptor to check for a token and put it in storage
axios.interceptors.response.use(response => {
// store the token client side (cookie, localStorage, etc)
if (response.data.token) {
localStorage.setItem('token', token)
}
return response
}, error => {
// Do something with response error
return Promise.reject(error);
});
// Use a request interceptor to add the Authorization header
axios.interceptors.request.use(config => {
// Get the token from storage (cookie, localStorage, etc.)
token = localStorage.getItem('token')
config.headers.common['Authorization'] = `Bearer ${token}`
return config;
}, error => {
// Do something with request error
return Promise.reject(error);
});
Accessing the Authenticated User
In order to get the user, pass the 'api' parameter to the auth() helper, Auth facade, or through the request:
$user = auth('api')->user();
$user = Auth::user('api');
$user = request()->user('api');
Keep in mind personal access tokens are long lived, so it's up to you to decide when and how they should expire.
Any http client can be used to make api requests, axios is a very common option and included with each Laravel installation.

Tymon JWT Laravel Vue refresh token stored in localstorage

So I started using Tymon JWT package for Laravel for my SPA. Its all going good ( adding user, signing in, getting Auth user) but when I make an API request it only works for an hour. I understand that the token I stored on on login expires so when I make a request to the API after 60 minutes it doesnt work. My question is how do I refresh the token and restore it in my local storage? On a new request? Every 59 minutes?
AuthController.php
public function authenticate(Request $request)
{
// grab credentials from the request
$credentials = $request->only('email', 'password');
try {
// attempt to verify the credentials and create a token for the user
if (! $token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'Sorry, we cant find you.']);
}
} catch (JWTException $e) {
// something went wrong whilst attempting to encode the token
return response()->json(['error' => 'could_not_create_token'], 500);
}
// all good so return the token
$user = JWTAuth::toUser($token);
//Fire off the login event
event( new LoginSuccessful($user) );
return response()->json( compact('token', 'user') );
}
Login.vue
axios.post('/api/authenticate',{
email: this.email,
password: this.password
})
.then(response => {
if(response.data.error){
//Show the error
this.error = response.data.error
this.loading = false;
} else {
this.loading = false;
//Store the items in storage
localStorage.setItem('jwt_token', response.data.token);
localStorage.setItem('user', JSON.stringify(response.data.user));
//Mutate the state
this.$store.commit('login');
//Now go to the dashboard
this.$router.push('dashboard');
}
})
.catch(error => {
});
in my head tag
<script>
window.hopbak = {
'jwt_token': localStorage.getItem('jwt_token'),
'csrfToken': {!! json_encode( csrf_token() ) !!},
};
</script>
in my bootstrap.js
let token = window.hopbak.jwt_token;
if (token) {
window.axios.defaults.headers.common['Authorization'] = 'Bearer ' + token;
} else {
console.log('no token');
}
I think you need to register the RefreshToken middleware in app/Http/Kernel.php:
protected $routeMiddleware = [
'jwt.refresh' => 'Tymon\JWTAuth\Middleware\RefreshToken'
];
And then assign it to the routes you want to refresh the token.
Looking at the source code, I can tell that this middleware will handle the refreshing of your token in every request by adding a new token to the response header.
JWT_TTL, JWT_REFRESH_TTL and JWT_BLACKLIST_GRACE_PERIOD values are setted in config/jwt.php file.
How does it work:
The client sends the credentials (email and password) to Laravel and
receives a token (JWT) in response. This token is valid for JWT_TTL
minutes. During this time all requests with the header Authorization
= "Bearer token" will be successful.
For a request made after JWT_TTL minutes, that is, with the token expired, two situations will occur: (1) If there is less than JWT_REFRESH_TTL minutes since the creation of the token (the token carries within it the date of creation on claim IAT), then this token will be invalidated (blacklist) and a new token will be generated and sent as a response to the client. JWT_REFRESH_TTL defines how many minutes after creating the first token the new tokens can be created. For example, for JWT_REFRESH_TTL = 21600, new tokens will be generated for 15 days, after which time the user should reauthenticate. (2) The request occurs after JWT_REFRESH_TTL minutes after the first token was created. In this case, it will not be possible to generate a new token for the client and it must authenticate again. A 401 error will be sent to the client.
When multiple concurrent requests are made with the same JWT,
it is possible that some of them fail, due to token regeneration on
every request. Set grace period in seconds to prevent parallel
request failure, because the JWT will consider to be valid for
JWT_BLACKLIST_GRACE_PERIOD seconds, even if it's on the blacklist.
For more details see this my explanation.

google ExchangeCodeForTokenAsync invalid_grant in webapi

i have implemented GoogleAuthorizationCodeFlow scenario from google api client dotnet and tutorial to get token from what my client sent to server as a code. but when i call flow.ExchangeCodeForTokenAsync , I get the following error :
{"Error:\"invalid_grant\", Description:\"\", Uri:\"\""}
I read google authorization invalid_grant and gusclass oauth 2 using google dotnet api client libraries but they didn't help me and. I think it must be very simple but I don't know why it doesn't work.
For client side , I have used Satellizer and this is my server Codes:
public bool PostExchangeAccessToken(GoogleClientAccessCode code)
{
string[] SCOPES = { "email" };
IAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets()
{
ClientSecret = "******",
ClientId = "********.apps.googleusercontent.com"
},
Scopes = SCOPES
});
try
{
TokenResponse token;
token = flow.ExchangeCodeForTokenAsync("*****#gmail.com", Newtonsoft.Json.JsonConvert.SerializeObject(code), "https://localhost:44301/",
CancellationToken.None).Result;
}
catch (Exception ex)
{
throw ex;
}
return true;
}
what is the problem?
On Github I found that I must use the Token from the client and use
GoogleAuthorizationCodeFlow.Initializer()
to create my UserCredential object.
You can check your google developer console settings.(Authorized redirect URIs)
Credentials => OAuth 2.0 client IDs => Your Application Settings => Authorized redirect URIs
You must add url. ("https://localhost:44301/")
My code :
flow.ExchangeCodeForTokenAsync("me", authCode, redirectUri, CancellationToken.None).Result;
Authorized redirect URIs
For use with requests from a web server. This is the path in your application that users are redirected to after they have authenticated with Google. The path will be appended with the authorization code for access. Must have a protocol. Cannot contain URL fragments or relative paths. Cannot be a public IP address.

Resources