I created an Aqueduct project using aqueduct create -t db_and_auth but I did not understand how registration and authentication with OAuth 2.0 works. Can someone explain how to register from OAuth2.0 and DB template auto-created by aqueduct and what steps I have to do to register and then authenticate?
From a client application, you POST /register with a JSON payload containing a user. Depending on what version of the template you have, this may just be {"username": "bob", "password": "password"} - check the definition of your _User type.
When you are authenticating an already existing user, you invoke POST /auth/token and pass the username, password and other required fields as x-www-form-urlencoded data. The format of that request - written in Dart code - is here: http://aqueduct.io/docs/auth/controllers/.
Whether you are registering a new user or authenticating an existing user, you have to provide a client identifier (and optionally client secret) as a Basic Authorization header. The client identifier must have already been registered with your application and stored in its database.
To store client identifiers in a database, you'll need to first run your application's database migrations on a database instance (see http://aqueduct.io/docs/db/db_tools/ for running database migrations). This will create tables to store OAuth 2.0 client identifiers and tokens.
Then you'll need to add OAuth2.0 client identifiers to your database. This is best accomplished using the aqueduct auth CLI, and there is documentation on it here: http://aqueduct.io/docs/auth/cli/.
Related
I'm implementing Google's 'code model' of Oauth2 and having trouble getting users' email - I wonder if this is a scopes problem or my misunderstanding about how to set up the code model. This sequence of events is already working:
Client loads https://accounts.google.com/gsi/client
Client starts call to google.accounts.oauth2.initCodeClient
Client gets code
Client passes code to one of my server endpoints
Server has an oauth2Client set up using the config with client_id, client_secret, and redirect URL = 'postmessage'
Server exchanges the code from the client for tokens
Server does oauth2Client.setCredentials(tokens) - this contains an access_token, which is enough for the client to make API calls to, e.g., retrieve the user's Google Calendar
Server is able to do oauth2Client.getTokenInfo(tokens.access_token);
There are various places along the way that involve scopes; I am probably getting something confused here. The client's initial call (step 2 above) uses
scope: 'https://www.googleapis.com/auth/calendar',
My code path on the server does define scopes anywhere.
In GCP, my project is set up with scopes
calendar.calendarlist.readonly, calendar.readonly and calendar.events.readonly
openid
/auth/userinfo.email
Here's the problem I'm encountering: when I go through this flow as a user and oauth with the account that owns the GCP project (this is a Google Workspace email, in case that matters), the tokens object that the server receives (step 6 above) has access_token, refresh_token and id_token - the id_token can be decoded to yield the user's email, and the user's email is also in the response to oauth2Client.getTokenInfo(token.access_token).
However, when I go through the flow with my other (personal) Gmail account, the tokens object that the server receives is missing the id_token but has the access and refresh tokens. Question 1: why are the responses different?
Question 2: How can I get the email of the user on the server in the personal Gmail account case? I've tried having the server make a call to https://www.googleapis.com/oauth2/v2/userinfo?fields=id,email,name,picture with the access_token, but this fails. I am not sure if I'm supposed to declare scopes for oauth2Client somehow, or tap a Google API using a different method on the server.
I think I've had a breakthrough: in step 2 in my original post, when I did "Client starts call to google.accounts.oauth2.initCodeClient", I had set the scope of initCodeClient to just the calendar scope. When I changed it instead to scope: 'https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/userinfo.email openid', (scope takes a space-delimited list in this case), it allowed my server call to get the id_token for this user and oauth2Client.getTokenInfo to get a response with the user's email in it.
When I updated the scopes like that, the popup asking for authorization also updated to request all the scopes I wanted - previously, it was only asking for the Calendar scope, so it makes sense Google didn't want to return the email.
What I still don't understand is why my previous setup was working for the account that owns the GCP project. In other words, when I was first building it out with that owner account, the client was only noting the Calendar scope while the server was asking for all three scopes (ie there was a mismatch), and the server was still able to get an id_token and the user's email in getTokenInfo. Maybe the owner account has some special privilege?
I’m updating a third party app that currently integrates with Twinfield using the session’s method with username and password to use the oAuth method.
In confused by the documentation though... do I still need to use the sessions or when using oAuth do I just call the endpoint(s) by passing the access token in the header as normal?
Also their Soap definition has four properties, the usual ClientID and Secret but also accessSecret? What’s that?
TLDR: you no longer need to use the sessions and SelectCompany; when you have the access token you can use that and the company code directly in the header.
You can obtain the access token as described here.
The documentation is a bit unclear on how to use the access token in your calls.
In the old username/password/session flow, you referred to a SessionID in the SOAP Header, and you would do a SelectCompany call to select the relevant target ("administratie").
In the OAuth flow, the SessionID is no longer relevant. Once you obtained a valid access token, you should set that in the header using the AccessToken field.
Instead of the old SelectCompany call, you can set the CompanyCode directly in the header. So if you have obtained an access token eyWhatANiceToken, and want to retrieve data for company "My Company BV [130001]" you have set AccessToken to eyWhatANiceToken and CompanyCode to 130001 in the header.
You can request the available codes using the list offices call
I don't understand the use of JWT token..
Can anyone explain it to me ?
Because currently i'm working on an app (rails + react), and I want to use devise + jwt for authentification and React for frontend.
Actually, I understood that :
1/ If a user want to login: he completes the form, React get Data from form and make a post request of these infos to Rails API.
2/ Rails API get theses infos check in the db if infos match with a registered user, if it is then Rails API will create a JWT token and will send this token to React.
User is now logged in because Rails API found a matched user.
3/ React receive the JWT token. ( ?? what the usage of this token ?? )
thanks
My response is not specific to Rails/React, but rather to all web technologies using JWT tokens:
What you said is correct. From point 3 forward, all the requests made from React to the Rails backend will have to contain the header Authorization: Bearer <token>.
When Rails sees that header, it is able to:
checks the token is valid, by checking its signature
decode it and extract any info stored in it.
Remember that JWT tokens can contain any info the backend wants to store in it. And the client is not able to tamper it, because it is signed cryptographically and it would invalidate its signature.
The above properties (the fact you can store anything in it, that the frontend sends it with every request and that nobody can tamper it) help any web application being able to:
have a shared nothing architecture - because the session is stored completely on the UI, so any backend worker/machine can handle any request
store more info in the session than if they'd use signed cookies for sessions.
Since you are return api . And react is consuming it.
Jwt help to return data you might need to persist in your frontend in react tho. Data like user name or email.
Example : making the header of your website show a user is logged in.
Since you are return api . And react is consuming it.
Jwt help to return data you might need to persist in your frontend in react tho. Data like user name or email.
Example : making the header of your website show a user is logged in.
The main aim of jwt in frontend is basically auth.
Apart .
If you are using a monolith app u deal with session for user
In react case jwt stands in as the session
The main aim of jwt in frontend is basically auth or other.
Apart . If you are using a monolith app remeber u deal with session for user In react case jwt stands in as the session
I am working on an LTI widget, that then needs to authenticate to the API to get additional information.
I'm struggling with trying to figure out how to process the API user authentication, and redirect back retaining the LTI information.
The request string that is returned looks like:
Array ( [x_a] => **********************
[x_b] => **********************
[x_c] => *********************************** )
The issue is that I have my PHP LTI script setup to only load if it meets the following condition:
if(!isset($_REQUEST['lis_outcome_service_url'])
|| !isset($_REQUEST['lis_result_sourcedid'])
|| !isset($_REQUEST['oauth_consumer_key'])
)
x_a is the user id, x_b is the user key .. what is x_c?
Any suggestions appreciated!
My answer is referring to the detailed topic on the IDKey Auth scheme for the Valence dev platform.
The part of the auth sequence you are referring to here is equivalent to the second stage of the sequence, just after the user has successfully authenticated themselves (when you chain on the back of an LTI launch like this, you know that the user driving the user-agent has already authenticated, because they wouldn't have otherwise been able to do the LTI launch) and the service sends back the long-lived user tokens to your service.
See steps 5 to 7 in the sequence notes, in the section called Using a third-party web application in the IDKey Authentication docs topic:
x_a={tokenID} – Unique ID associated with the long-lived token: the web application can provide this ID so that the service can precisely locate the web application/user context.
x_b={tokenKey} – Key associated with the long-lived token: the web application can use this as a key to generating session signatures.
x_c={tokenSig} – Token identity signature: the service joins (and delimits with an ampersand) the User ID (tokenID) and the User Key (tokenKey) to use as the base-string, and uses the Application Key as the key.
Note that you will need to use your Valence Application ID/Key pair in order to verify the token signature contained in x_c.
Remote plugins. Note that the Brightspace Remote Plugin service is a convenience service wrapper around LTI/external learning tools. The docs about Remote Plugins contain a fairly detailed walkthrough/sample that showcases a simple Python web-service Tool Provider implementation that receives a Brightspace LTI launch, and can turn around and use Valence API calls to get more information. You might find it useful to have a close look at that.
The Eventbrite documentation on the ticket object indicates that it can contain a quantity_available or quantity_sold field, but that to see either of these fields "requires authentication". It doesn't give any more detail than that, though, and when I make calls to the event_search method using my app key, the tickets objects in the returned events do not contain quantity_available or quantity_sold keys.
What authentication is required to see these fields? Are they only visible to the owners of the event, or is it possible in some way for me to have the API return the number of tickets available for somebody else's event?
If this is not possible through the API, is the number of tickets remaining for an event publicly visible anywhere else on Eventbrite where I could get to it with a web scraper?
This needs to be called as an expansion. There are some more details here:
https://groups.google.com/forum/#!msg/eventbrite-api/sjMO-gV8-Go/uzw7GHq2_SEJ
Basically, calling it like so will populate the proper fields using your Apps OAuth token in python3:
import requests
eventbrite_response = requests.get(
"https://www.eventbriteapi.com/v3/events/<YOUR EVENT ID HERE>/?expand=ticket_classes",
headers = {
"Authorization": "Bearer <YOUR APP OAUTH TOKEN>",
},
verify = True, # Verify SSL certificate
)
print(eventbrite_response.json()['ticket_classes'][0]['quantity_sold'])
You can tailor the print function at the end to include more of the json data if you wish.
In order to read or write private data using the Eventbrite API, you will need to supply additional user-authentication tokens. This extra information lets Eventbrite know who should be authorized to access private data (including quantity_available and quantity_sold values) during the request.
Whenever you provide additional user access tokens, both public and private data will be available.
Authentication parameters include:
app_key: An application key (also referred to as an API key), identifies the application that is contacting the API. All API requests must include some form of application identification. If this is the only authentication token provided, the API request will be limited to publicly available data. Application keys have a default rate-limit of 1000 requests per day. You can get and manage your API keys here: https://www.eventbrite.com/api/key/
access_token: Recommended. OAuth2 access tokens are tied to a user account and an application key. Since the user-authorized application can also be identified via this token, it is the only authentication parameter that does not require an application key to be provided as well. Be careful not to expose these tokens to other users! Additional request headers are required when using access_tokens to contact our API: “Authorization: Bearer YOUR_ACCESS_TOKEN_HERE“. You can learn more about how to configure your application for OAuth2.0 here: http://developer.eventbrite.com/doc/authentication/oauth2/
user_key: Each Eventbrite account has an associated user_key. This token provides access to the related user’s account data, in addition to our publicly available data. This authentication method is preferred for use-cases that require private data-access where OAuth2.0 workflows are not possible. This token unlocks sensitive information, so be very careful not to expose this token to other users!
Here is an example of an API call that is using both the app_key and user_key parameters to return private data (remember to substitute in your own app_key and user_key):
https://www.eventbrite.com/json/user_list_events -G -d app_key=APPKEY -d user_key=USERKEY
You can also see the authentication documentation here: http://developer.eventbrite.com/doc/authentication/