You can sign users in to a Turnkey application from trusted server-side logic, use signed tokens for passwordless access, and authenticate calls to REST services without showing a password form. This page is for developers building custom login flows, magic links, app-managed sessions, or service-to-service calls.
Choose the login approach
Use the approach that matches how the user or client reaches your application.
| Situation | Use | Example |
|---|---|---|
| A trusted system needs to sign a person in without asking for a local password | Signed JWT login | Your mobile-app backend issues a time-limited token for person@example.com; the app uses that token to establish a Turnkey login.
|
| You need a passwordless recovery or invitation flow | Signed JWT login with a short validity period | You email a link that signs the intended recipient in after Turnkey verifies the token signature and validity period. |
| A technical actor needs revocable access | Signed JWT login and managed signing keys | Issue a token for an integration account. Stop accepting tokens signed with a key when that key is no longer trusted. |
| Existing code must submit the standard Turnkey login form | Legacy MVC form post | A desktop utility obtains the MVC anti-forgery token from the login page and posts the email and password. |
| A client calls an exposed REST service | Basic authentication, bearer token, or a client-certificate-signed request | A Turnkey app calls another service through selfVM.RestGet and supplies credentials or a bearer token.
|
Log in with a signed JWT
A JSON Web Token (JWT) is a signed token that identifies a user and has a validity period. Treat it as a passport: Turnkey can trust the identity in the token only after it verifies that a trusted party signed it and that the token is valid.
JWT login lets you avoid collecting a password in the client. Typical uses are:
- Logging a user in from an installed application.
- Sending a passwordless sign-in or recovery link.
- Giving a technical actor access that you can stop by changing which signing keys are trusted.
JWT login flow
- Create or use a trusted token issuer. This can be your own server or another trusted party.
- Issue a JWT that identifies the intended user and includes an appropriate start and end date.
- Configure Turnkey to recognize the signing key used for the token.
- Send the token to the Turnkey JWT login flow from the client.
- Turnkey verifies the token before establishing the user login.
For example, a server can issue a long-lived token for a specific mobile-app user. When the app starts later, it presents that token and the user can be logged in without entering a password. If the token or signing key is no longer trusted, replace or deactivate the relevant key so tokens signed by it no longer validate.
Do not expose a server-side capability that logs in an arbitrary user directly to untrusted client code. A custom login page can pass a username and password through the transient login-request values and invoke the password login controller, but a flow that chooses the logged-in user must remain server-side. See the login override walkthrough.
For JWT validation and REST JWT authentication details, see Documentation:Authenticate with a jwt. The JWT and SAML2 walkthrough demonstrates issuing a token, logging in with it, and rejecting a token when its signing-key identifier is no longer available.
Design a safe magic-link flow
Use a magic link only when you can protect the token as a credential.
- Create a token for one intended user.
- Set a limited validity period appropriate to the purpose. For example, use a short-lived token for password recovery rather than the longer-lived token an installed app may need.
- Deliver the link only through the channel you intend the recipient to control.
- Let Turnkey validate the signature and validity period before login.
- Plan how you will revoke trust. Changing which signing key is accepted prevents further use of tokens signed with the removed key.
A JWT is not trustworthy because it contains an email address. It is trustworthy only when Turnkey can verify its signature against a trusted key and the token is within its valid period.
Legacy: post the MVC login form from code
Turnkey uses MVC for its password login form. The form uses __RequestVerificationToken, an anti-forgery value that helps MVC reject reuse of an old posted form. If code posts directly to this form, it must first obtain a valid request-verification token and include it in the post.
This is an older approach. Prefer signed JWT login when you need a passwordless, logic-controlled sign-in flow. Use the form-post approach only when you must automate the existing password login form.
Steps
- Request the Turnkey
Account/Loginpage. - Read the returned HTML and extract the
__RequestVerificationTokeninput value. - Post the login fields
EMail,Password,RememberMe, and__RequestVerificationTokentoAccount/Login. - Check the response and handle unsuccessful authentication in your client.
The following example shows this pattern. Replace the server URL and credentials with values appropriate for your application.
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var client = new HttpClient();
var loginform = client.GetAsync(
"https://raptor3ny/TurnkeyWebAppGeneric/Account/Login").Result;
var loginformcontent = loginform.Content.ReadAsStringAsync().Result;
var part1 = loginformcontent.Substring(
loginformcontent.IndexOf("<input name=\"__RequestVerificationToken\""), 1000);
part1 = part1.Substring(part1.IndexOf("value="));
part1 = part1.Substring(part1.IndexOf('"') + 1);
part1 = part1.Substring(0, part1.IndexOf('"'));
var content = new MultipartFormDataContent();
content.Add(new StringContent("hans@karlsen.se"), "EMail");
content.Add(new StringContent("123456"), "Password");
content.Add(new StringContent("false"), "RememberMe");
content.Add(new StringContent(part1), "__RequestVerificationToken");
var result = client.PostAsync(
"https://raptor3ny/TurnkeyWebAppGeneric/Account/Login", content).Result;
if (result.StatusCode == System.Net.HttpStatusCode.OK)
{
// Login successful
}
}
Limits of the legacy approach
The example extracts the token by searching the returned HTML and taking a fixed-length substring. That makes it dependent on the login page markup. Keep it as a compatibility pattern, not as the basis for a new passwordless login design.
Authenticate REST calls
When Turnkey hosts REST services, it checks for Basic authentication in the request Authentication header. The Basic-authentication value contains user:password encoded as Base64. Turnkey unpacks that value and resolves it against SysUser.
For example, a client using user integration@example.com and its password can send Basic authentication when it calls a Turnkey REST endpoint. Base64 encoding is not encryption; protect credentials and tokens in transit.
Send credentials with selfVM.RestGet
When you call selfVM.RestGet and related methods, you can supply a user name and password. When both are set, Turnkey adds them as a Basic-authentication header. This supports communication between Turnkey applications and with other REST implementations.
To send a bearer token instead:
- Set the user value to
Bearer; this comparison is case-insensitive. - Set the password value to the bearer token.
- Turnkey sends an
Authenticationheader containingBearerand the supplied token. The casing ofBeareris retained from the value you provide, which can matter to strict services.
You can also sign a REST request with a client certificate; see Sign client rest request with certificate.
Related authentication options
JWT login is different from external identity-provider login. For OpenID Connect, Turnkey receives a short-lived authorization code through a registered callback and exchanges it for tokens. See Documentation:How does OpenIdConnect work.
If a browser-based single-page application calls Turnkey REST services with an external token, configure the accepted origin, audience, and external JWT signing-key definitions as described in Documentation:Connecting javascript SinglePageApplications to Turnkey (SPA).
If your organization uses social or external login and does not want local password registration, see Documentation:Hide Password login. If a user is stuck at the external-login registration page, see Documentation:External login screen problem.
