Xero API authentication without OAuth2 - php

The scenario
So I am building an app that should display data from my Xero account to the users. Users should not be able to login via OAuth2 to my web app so that's why I need persistent auth token that is independent from the users login. The current API authentication implementation from Xero does not allow that and the token expires in 30 minutes so I need a way to do this somehow in the background or with any kind of persistent token (which is not available as I can see in their docs for Auth)
Stack
I am using Laravel with the package Xero Laravel and this one's using the XeroPHP package in its core as dependency. Currently I am using Postman to do refresh token requests and I am adding the token manually (for testing purposes of course). This should not be the case when it goes on production, though. So I need a way to somehow "store" or refresh the token globally for the whole app and using only my account as an Authorization to Xero.
Problem summary
My web app need to fetch data (invoices data in particular) from my Xero account and no OAuth tokenization is required for the users (since I am using the native Laravel Auth for this purpos) that are going to read this data in a GUI.
How should I accomplish this without OAuth2 (if there is any way) or how I can do this if only my account is the "global" one for the app?

The other comments are correct that there is an initial required step to have the user that you are calling API endpoints on behalf of to authorize your API application.
Once you have their valid token_set ( access_token, refresh_token, expiry, etc.. ) you can store that securely and continue making offline_access api calls on their behalf. Note that you must programmatically refresh the token_set at least once every 60 days for it to remain valid.
I'd also recommend checking out the Xero supported libraries for help getting started quickly:
https://github.com/XeroAPI/xero-php-oauth2
https://github.com/XeroAPI/xero-php-oauth2-starter
Thanks to #droopsnoot for linking the video explaining how this works:
https://www.youtube.com/watch?v=Zcf_64yreVI

Related

Central OAuth2.0 Authorization on the Backend-Side using PHP and curl for Spotify Web API

I am creating an application which aims at automatically creating Spotify Playlists in a central Spotify account (not the account of the end users).
I have set up this account and created the developer app for the secret and the client_id.
On the backend side, I am using PHP to authorize this central user, and it is working as long as I am logged in myself with that account.
Users that visit my website should be able to create playlists via that interface through the Spotify Web API without the need to authorize their account nor being logged in at all.
If I'm trying to open the same page on a separate device (without having any account logged in), it just gives me the following error:
User not registered in the Developer Dashboard
Is it somehow possible to perform this authorization process only on the backend side without the need for the user to authorize it?
Eventually, I want to send the playlist URL created in the central Spotify Account to the user who can open it in their own app or share with others, if they want to.
I try to avoid that multiple users must authorize for my app, since I don't need to access personal information from their account, anyways.
I used the 3-step process for authorization as described in this Stackoverflow Post: Spotify oauth2 with PHP curl. How to get authorization code?
If necessary, I will provide more information.
Do you have any idea, how I can implement this authorization process for the single account on the backend side, without the user even showing any authorization process of the Spotify Web API at all?
EDIT1: I am not trying to login on the behalf of my users, just automatically for my own account without the interactive login with Spotify. Is that even possible?
I received valuable feedback from the Spotify Developer Community that helped me finding a solution to the problem.
When you let the central Spotify account login to your app, you'll [get] an access_token (that will expire in 1 hour) and a refresh_token.
When the access_token of that account expires, let your server send a POST request to the Accounts service /api/token endpoint, but use the refresh_token in place of the access_token.
A new access_token will be returned.
A new refresh_token might be returned too. (I don't think that's even needed)
You can read more about it here.

How to Implement OAuth correctly in API with Laravel Passport?

I'm trying to create an API and use it in my own applications (web application and native mobile app) and make it available for third-party applications ( this is for future purposes).
I've read the Laravel Passport documentation, and I have some doubts that hopefully someone could help me with it.
As a developer, I always try to find the best and correct way to implement my projects and find the appropriate packages for the purposes of the projects.
Brief explanation of what I want to do:
I want to create an API and I will consume my own API in my web and mobile applications, my API has two endpoints for register and login for students and teachers. They can login with their email and password. Each user type has its own information. A teacher can have a CV, and students can see teachers' CV( the whole creating and reading CV's are handling in my API ), and they both user types can communicate with each other. I'm using laravel 6.x version to build my API. We have a section for developers in our subdomain which developers can register accounts and get/buy an access token to make requests to my API and use it, on the other hand, I want when students or teachers login to their accounts the API generates an access token for that user so then my application can use that token and pass that in every requests to make users be authenticated to access their private resources like their Dashboard as we know API's are stateless and we can't use sessions to store user credentials, so we need an access token for that.
Can Laravel Passport generate the both Developer access token, and User( teacher or student) access token?
Is it correct to use OAuth in here to develop my API?
Or can I just use tymondesigns/JWT package for these purposes?
I have to say that I'm new to Oauth and API based applications. I've read some articles about Oauth, and I'm a little bit familiar with Oauth terminology, but still, I don't know how to implement this project correctly.
So here are my questions:
What is exactly Oauth server? Is it my own server that is hosted by API?
After Laravel Passport configuration and database migration, Laravel Passport created some tables in my database, I would be really appreciated if you could tell me what is the purpose of each tables? table names are failed_jobs, oauth_access_tokens, oauth_auth_codes, oauth_clients, oauth_personal_access_clients, oauth_refresh_tokens.
I've configured my Laravel application to use the Laravel Passport and I created two Routes in my api.php file
Route::post('login','API\Auth\UserAuthController#login');
Route::post('register','API\Auth\UserAuthController#register');
and then, I created the UserAuthController.php file and wrote the login and register methods. They are working without any problem. After a user registers or login into their account, my code will generate a personal access token.
$token = $user->createToken('authentication')->accessToken;
and then students or teachers can access to the private resources of their own with this access token. Is it right to create a personal access token for my two types of users? What is exactly a personal access token?
I just know you can pass it into request header, and the server will authorize you to access private resources. what I mean by private resources is the endpoints which are protected by API middleware like this:
Route::post('/update-info','API\Auth\UserAuthController#update')->middleware('auth:api');
Am I doing right to create a personal access token when teachers and students login to their account or I should do another way to handle it?! this way works, but I'm looking for correct way if there is anything else.
The weird thing here is Laravel Passport create a token every time users login and it doesn't check if they have already created token or not? If someone can access the API endpoint, they can make a post request to /login endpoint and create a lot of tokens. Is it a problem? How to fix it?
When I create a personal access token I need to pass an argument to createToken($arg) method, and it stores in oauth_personal_access_clients table. what is the purpose of this? Is it just for Laravel Passport purpose, or maybe I need it in the future?
I have some endpoints which are not protected by auth:api middleware, for example, every user visit my application they can search for teachers name and lessons and ... , it's not necessary to make them login or register first. These endpoints are accessible to everyone in my application, and they are free to search and advance search for some information. My question is if I make it accessible to everyone, how can I protect these endpoints that only my first-party app and third-party app can access them. I mean I don't want people to access them by command line or postman or some kind of these tools without access token, I want to protect these endpoints from attackers not to make a huge requests to make my server down. How can I protect this kind of endpoints? I know I can limit requests per minute, but I don't know how much limit it? Is there any other way?
I see there is a term called clients in Oauth terminology, as I understand clients are the applications like web applications or native mobile app and any other applications that use my API are called clients. Am I right? And I think this is for third-party application authentication. I'm a little bit confused after reading Laravel Passport documentation about clients, and when I configured the Laravel Passport, it generates two clients and stored them in database. Do I need to create a client for my Applications?! How Can I ignore authorization flow just for first-party applications?
After Laravel Passport configuration, now I can see it generates some default route for clients.
/oauth/clients
/oauth/clients/{client-id}
/oauth/authorize
/oauth/token
What is the usage of these routes?! do I need them to create my first-party applications?
As I said the future purpose of this application is to make the API accessible by third-party applications, I have to create a web page that developers register an account and get/buy a token to access my API. is it possible to do it with Laravel Passport or I should write my own logic to make it work? Do I need to create a client for my third-party clients?
Thanks a lot for your help <3
It's going to take too long for me to answer each of your questions in depth, so I've
tried to link to the relevant sections in the RFC for further reading.
Essentially, I would recommend for you to use the password credentials grant flow for your first-party clients (your mobile app and web app). One of the clients that
Laravel would have created for you, would have been the "Laravel Password Grant Client" and its
documentation is available here.
You would still need to define your own "register" route, but you can use the oauth/token route
instead of your own /login route.
What is exactly Oauth server? Is it my own server that is hosted by API?
The OAuth server would be your server that is running Passport. Or in the official
terminology according to the RFC, the
OAuth server/Passport server would be called the "authorization server."
In your case, the "resource server", which your API that serves your content, would be
the same server as the "authorization server."
After Laravel Passport configuration and database migration, Laravel Passport created some tables in my database, I would be really appreciated if you could tell me what is the purpose of each tables? table names are failed_jobs, oauth_access_tokens, oauth_auth_codes, oauth_clients, oauth_personal_access_clients, oauth_refresh_tokens.
The failed_jobs table is not directly related to Passport. It's related to Laravel's queues. See Dealing With Failed Jobs.
The rest of the tables are all there so that Passport can keep track of the clients and codes it has created.
oauth_clients: See the RFC clients section.
oauth_access_tokens: See the RFC access tokens section.
oauth_auth_codes: See Authorization Code Grant.
oauth_personal_access_clients: Personal access clients don't seem to be part of the official specification, but it is basically a client for when a user wants to get an access token directly, instead of going through an app or website. Usually this would be a developer who wants to get an access token to be able to call API endpoints on their own account.
The personal access clients table stores clients that were specifically created for this purpose. Usually there would
only be one of them.
oauth_refresh_tokens: See the RFC refresh tokens section.
Is it right to create a personal access token for my two types of users? What is exactly a personal access token?
Every user would need to get their own access token, but not a personal access token.
Personal access tokens are just access tokens that were created specifically for users who wants to generate
and use the access token themselves. In Laravel Passport, specifically, they are access tokens
which are linked to the "Laravel Personal Access Client."
So in your case, your server would create "normal" access tokens for users and not "personal" access
tokens.
Am I doing right to create a personal access token when teachers and students login to their account or I should do another way to handle it?! this way works, but I'm looking for correct way if there is anything else.
See answer to question 3.
The weird thing here is Laravel Passport create a token every time users login and it doesn't check if they have already created token or not? If someone can access the API endpoint, they can make a post request to /login endpoint and create a lot of tokens. Is it a problem? How to fix it?
I don't think this is a problem. The oauth/token route is rate-limited. You can rate-limit it even more.
You can also listen to events and delete or revoke tokens
if want to limit the amount of tokens there may be for a single user.
When I create a personal access token I need to pass an argument to createToken($arg) method, and it stores in oauth_personal_access_clients table. what is the purpose of this? Is it just for Laravel Passport purpose, or maybe I need it in the future?
This table is just for Laravel Passport. It can also be of use for when you want to audit or debug something later on.
The row that you see in the oauth_personal_access_clients table, was created when you ran php artisan passport:install.
When you call createToken, a new row is inserted into oauth_access_tokens.
I have some endpoints which are not protected by auth:api middleware, for example, every user visit my application they can search for teachers name and lessons and ... , it's not necessary to make them login or register first. These endpoints are accessible to everyone in my application, and they are free to search and advance search for some information. My question is if I make it accessible to everyone, how can I protect these endpoints that only my first-party app and third-party app can access them. I mean I don't want people to access them by command line or postman or some kind of these tools without access token, I want to protect these endpoints from attackers not to make a huge requests to make my server down. How can I protect this kind of endpoints? I know I can limit requests per minute, but I don't know how much limit it? Is there any other way?
Yes, you'll have to do rate-limiting. You'll have to experiment and see what works for you.
I see there is a term called clients in Oauth terminology, as I understand clients are the applications like web applications or native mobile app and any other applications that use my API are called clients. Am I right? And I think this is for third-party application authentication. I'm a little bit confused after reading Laravel Passport documentation about clients, and when I configured the Laravel Passport, it generates two clients and stored them in database. Do I need to create a client for my Applications?! How Can I ignore authorization flow just for first-party applications?
Yes, clients are like web applications, mobile apps, etc. Usually you would have a new
client for every mobile app, web app, CLI, etc., but in addition to those apps, Laravel defines
the "Password Grant Client" and the "Personal Access Client" clients for you which have
specific purposes.
You can use the Laravel Password Grant Client for
both of your applications since they're first-party applications.
You can ignore the authorization flow for first-party applications by using the
/oauth/token route that is provided for
password grant clients.
The RFC section about the password credentials flow is available here.
You can read more about how the RFC defines clients here.
What is the usage of these routes? do I need them to create my first-party applications?
Needed for first-party applications:
/oauth/token
Not needed for first-party applications:
/oauth/clients: this is for a third-party developer to see which clients they have created.
/oauth/clients/{client-id}: for a third-party developer to update one of their clients.
/oauth/authorize: this route will be called by a third-party developer to start the
authorization grant flow with their client ID and secret.
You can read more about the above routes under the "JSON API" section in Managing clients.
As I said the future purpose of this application is to make the API accessible by third-party applications, I have to create a web page that developers register an account and get/buy a token to access my API. is it possible to do it with Laravel Passport or I should write my own logic to make it work? Do I need to create a client for my third-party clients?
Laravel Passport provides Vue components that you can use so that developers will be able to create clients. You can either use these components or you can create your own frontend and call
the JSON API routes from your own frontend.
Keep in mind that OAuth was designed originally for when third-party apps needs to access things on behalf of a user. So instead of getting access tokens, third-party apps will get a client ID and client secret and they will need to go through one of the authorization grant flows for each user that they want to act on behalf of.
If you're never going to have third-party apps that need to act on behalf of users, it might be worth considering other protocols like mentioned in the comments.

Quickbooks online API with oauth2

I need to use Quickbooks online API to synchronize data between my system and my client's accounts on quickbooks.
I need to know if is it possible to complete the oauth2 authorization flow and make API calls without human interaction (without the need to interact with Intuit's authentication and authorization windows)?
I read the Intuit's docs on: https://developer.intuit.com/docs/0100_quickbooks_online/0100_essentials/000500_authentication_and_authorization/connect_from_within_your_app
On the first step, I made a GET request to:
https://appcenter.intuit.com/connect/oauth2?client_id=MY_ID&scope=com.intuit.quickbooks.accounting&redirect_uri=https%3A%2F%2FMY_NGROK_URL.ngrok.io%2FOAuth2PHPExample.php&response_type=code&state=RandomState#/Authorize/COMPANY_ID
Then, the Intuit's authentication and authorization windows opens and I need to put my username and password and then, click in the authorize button to get the authorization code.
Is there a way to obtain the authorization code without authenticate and authorize?
I need to automate this task to make API calls in the backend with PHP.
Thanks,
Marcelo.
Is there a way to obtain the authorization code without authenticate and authorize?
No... but read below.
I need to automate this task to make API calls in the backend with PHP.
You are misunderstanding how OAuth (either 1 or 2) works.
The very first time you connect you will be prompted to authenticate/authorize access to the QuickBooks Online data.
You are then given a refresh token (or access token depending on if you're using OAuth2 vs. OAuth1).
You then store that refresh token (or access token for OAuth1) and can use that token going forward to make your requests, unattended, without requiring the user to be involved at all.
Key take-away: You only need the user involved the VERY FIRST TIME you connect, and then never again.

auth0 authentication for react-native-ios that communicates with php server

I am creating an react-native-ios app that communicates with a php web app hosted on azure.
How I understand it works:
The user signs up to the app, the server communicates with auth0 server which then returns a JWT token to the php server, saves the token to the database and then sends the token back to the client-device where it is then stored on device.
The user must send the JWT token as a header whenever communicating with the server.
Whenever the user logs out the token is deleted and when signing in, a new JWT must be received.
The user can sign in via using credentials that match what is on the database or sign-in with Google or facebook.
Or is Auth0 just for signing-in with enterprises such as Google or can I use it to sign in to my app also that has login credentials on the database?
I have found the
npm react-native-lock-ios but it doesn't work the way I described above.
In summary, How should I go about this and is what I have explained above correct?
The main problem here is that you did not understand how to work with JWTs. I would advise you to take a deeper look on how this technology works and how Auth0 can help you. But, in summary, this is the workflow for authentication that you must aim:
Your user will choose one of the many identity providers supported by Auth0(e.g. Facebook, Twitter, LinkedIn, SAML, WS Federate and so on).
Your react native app will communicate directly to Auth0 API through the react native lock.
Auth0 will interface with the chosen provider and redirect the user to an authorization page in this provider (case it is needed and it is the first time the user logs in).
Auth0 will generate a JWT and send back to your react native app.
Your react native app will send this JWT to the server (usually on the Authorization HTTP header) when issuing requests to your endpoints.
Your PHP backend will check if this JWT is really valid. This is can be done with Auth0 PHP SDK.
In case the JWT sent has not been tampered (changed irregularly), your backend will accept it as the user identifier and respond the request as expected by your react native app.
As you can see the biggest issue in the approach that you thought you would follow is that the login process does not go through your backend server. It happens on your front-end app (react native) communicating with Auth0 and the identity provider chosen.
JWTs are tokens that hold information (claims) about a subject. These tokens can be validated by anyone that possess a key (public or private). That is, having this key you can validate the token and can rest assured that it has not been changed improperly.
Further more, to answer the question regarding the usage of Auth0 with credentials on your database, you can bet that you can use it. Auth0 provides ways to integrate with your own database to check the existence of a user. This is called a customer user store.
Happy studying.

How to access own API in native application using Google OAuth 2.0 for authentication?

We have an app that uses the OAuth2 Google sign-in system and we want to store data from the users that sign in into our app on our back-end during the initial registration.
This is the way we got it set up:
Users signs in with the app using Google sign-in
We get an ID Token and send this to the server
On the server we verify this token is valid using Google library and save the info we get back from the verification
We also need the user to be able to update/insert data into the back-end when he's authenticated.
After the initial registration, how do we do this?
Do we send the ID Token from client to server each time they call the API on our back-end? In this case how to handle expired tokens?
If you want to make your API a first-class citizen in your system and have it require access tokens that are specifically issued to it instead of accepting Google authentication related tokens that were issued to your client application then you need to have an authorization server that specifically issues tokens for your API.
This authorization server can still delegate user authentication to Google, but then after verifying the user identity it will issue API specific access tokens that better satisfy your requirements, like for example, including specific scopes then used by your API to perform authorization decisions.
For a more complete description of this scenario you can check Auth0 Mobile + API architecture scenario.
In this scenario you have a mobile application ("Client") which talks to an API ("Resource Server"). The application will use OpenID Connect with the Authorization Code Grant using Proof Key for Code Exchange (PKCE) to authenticate users.
The information is Auth0 specific and you can indeed use Auth0 as an authorization server for your own API while still maintaining Google authentication support, however, most of the theory would also apply to any OAuth 2.0 compliant provider.
Disclosure: I'm an Auth0 engineer.

Categories