Gives the two tokens every call may need : the token of an API user (which application calls, sent in x-am-authorization) and the token of a person, a row of your own users table read by a DB token generator (sent in x-am-user-authorization). See the two gates.
Method
POST
URL
/api/system-api/admin/token : admin is the user path of your account
Body
{ u, p, expiresInSeconds? }, { name, u, p }, { refresh_token, name? }, or an array of them
Answer
data : { token, refresh_token, expires_in }, or an array
expiresInSeconds is optional : Tokens Expire After of the Deployment Settings otherwise (72 hours by default).
The password of an API user lives in the secret, under the path set on the API user (common.apiUserPasswords.default for the API user of a new account).
The generator (an auth provider of type DB) knows the users table and its username and password columns. A hashed password column works : the password given is hashed and compared.
The groups of the person come from the groups column of the generator.
refresh_token of an earlier answer gives a new token without the password. For a person, add the name of the generator. A refresh token is valid refreshTokenValidForS seconds (900 by default) after the token expired.
When the generator reads a users table of a multi-tenant instance, name the tenant : the person is read from the database of that tenant, and the token works for that tenant only, also after a refresh.
constdatabaseUser=awaitg.sys.system.getToken({"name":"TOKEN_GENERATOR_NAME","u":"USER_NAME","p":"PASSWORD"});// databaseUser.token goes in x-am-user-authorization, databaseUser.refresh_token gets a new one later
database_user=awaitg.sys.system.get_token('USER_NAME','PASSWORD',name='TOKEN_GENERATOR_NAME',)# databaseUser.token goes in x-am-user-authorization, databaseUser.refresh_token gets a new one later
$databaseUser = $g->sys->system->getToken( 'USER_NAME', 'PASSWORD', name: 'TOKEN_GENERATOR_NAME',);// databaseUser.token goes in x-am-user-authorization, databaseUser.refresh_token gets a new one later
vardatabaseUser=awaitg.Sys.System.GetToken(newGetToken("USER_NAME","PASSWORD"){Name="TOKEN_GENERATOR_NAME",});// databaseUser.token goes in x-am-user-authorization, databaseUser.refresh_token gets a new one later
databaseUser,err:=g.Sys.System.GetToken(am.GetToken{Name:"TOKEN_GENERATOR_NAME",U:"USER_NAME",P:"PASSWORD",})iferr!=nil{returnnil,err}// databaseUser.token goes in x-am-user-authorization, databaseUser.refresh_token gets a new one later
letdatabase_user=g.sys.system.get_token(GetToken::new("USER_NAME","PASSWORD").name("TOKEN_GENERATOR_NAME"),)?;// databaseUser.token goes in x-am-user-authorization, databaseUser.refresh_token gets a new one later
vardatabaseUser=g.sys.system.getToken(newGetToken("USER_NAME","PASSWORD").name("TOKEN_GENERATOR_NAME"));// databaseUser.token goes in x-am-user-authorization, databaseUser.refresh_token gets a new one later
valdatabaseUser=g.sys.system.getToken(GetToken("USER_NAME","PASSWORD").name("TOKEN_GENERATOR_NAME"),)// databaseUser.token goes in x-am-user-authorization, databaseUser.refresh_token gets a new one later
const[apiUser,databaseUser]=awaitg.sys.system.getToken([{"u":"USER_NAME","p":"USER_PASSWORD"},{"name":"TOKEN_GENERATOR_NAME","u":"USER_NAME","p":"PASSWORD"}]);// apiUser.token goes in x-am-authorization, databaseUser.token in x-am-user-authorization
api_user,database_user=awaitg.sys.system.get_tokens([GetToken('USER_NAME','USER_PASSWORD'),GetToken('USER_NAME','PASSWORD',name='TOKEN_GENERATOR_NAME'),])# api_user.token goes in x-am-authorization, database_user.token in x-am-user-authorization
[$apiUser, $databaseUser] = $g->sys->system->getTokens([ new GetToken('USER_NAME', 'USER_PASSWORD'), new GetToken('USER_NAME', 'PASSWORD', name: 'TOKEN_GENERATOR_NAME'),]);// $apiUser->token goes in x-am-authorization, $databaseUser->token in x-am-user-authorization
vartokens=awaitg.Sys.System.GetTokens([newGetToken("USER_NAME","USER_PASSWORD"),newGetToken("USER_NAME","PASSWORD"){Name="TOKEN_GENERATOR_NAME"},]);var(apiUser,databaseUser)=(tokens[0],tokens[1]);// apiUser.Token goes in x-am-authorization, databaseUser.Token in x-am-user-authorization
tokens,err:=g.Sys.System.GetTokens([]am.GetToken{{U:"USER_NAME",P:"USER_PASSWORD"},{Name:"TOKEN_GENERATOR_NAME",U:"USER_NAME",P:"PASSWORD"},})iferr!=nil{returnnil,err}apiUser,databaseUser:=tokens[0],tokens[1]// apiUser.Token goes in x-am-authorization, databaseUser.Token in x-am-user-authorization
lettokens=g.sys.system.get_tokens(vec![GetToken::new("USER_NAME","USER_PASSWORD"),GetToken::new("USER_NAME","PASSWORD").name("TOKEN_GENERATOR_NAME"),])?;let(api_user,database_user)=(&tokens[0],&tokens[1]);// api_user.token goes in x-am-authorization, database_user.token in x-am-user-authorization
List<TokenResponse>tokens=g.sys.system.getTokens(List.of(newGetToken("USER_NAME","USER_PASSWORD"),newGetToken("USER_NAME","PASSWORD").name("TOKEN_GENERATOR_NAME")));TokenResponseapiUser=tokens.get(0),databaseUser=tokens.get(1);// apiUser.getToken() goes in x-am-authorization, databaseUser.getToken() in x-am-user-authorization
val(apiUser,databaseUser)=g.sys.system.getTokens(listOf(GetToken("USER_NAME","USER_PASSWORD"),GetToken("USER_NAME","PASSWORD").name("TOKEN_GENERATOR_NAME"),),)// apiUser.token goes in x-am-authorization, databaseUser.token in x-am-user-authorization
The token API is public by default : anybody can ask for a token with a username and a password.
When its system API settings list auth providers, it needs the tokens those settings ask for, like any other API.
A token is a JWT signed with passJWT of the server. Changing the password of the API user, or passwordChangedAtColumn of a person, invalidates the tokens made before.
The token API is open to everybody : that is how a caller gets its first token. Its settings change that only when they name authProviders. An incomplete body answers 400 : Please provide token request with ['u', 'p'] or ['refresh_token'].
Over HTTP, a system API answers only once its settings open it : TOKEN_ACCESS (the token of an API user whose group grants this system API) or IS_PUBLIC. Without settings it is NO_ACCESS : only your code (g.sys) and the admin panel reach it.
The settings can also keep the answer in the cache, or ask for the token of a person (authProviders). Pre and post hooks run around it, as around any API.
It takes the request headers and answers the envelope. 401 : no valid token, or the API is NO_ACCESS. 403 : no group grants it. 400 : the body is wrong, and the message names the key.