Send tokens, not profile data, to your server

2026/08/13

When integrating LINE Login or developing a LINE MINI App, you may notice that you can get profile information such as an end user's user ID and display name. It might seem that you can send the profile information to your service's server and use it as is for login or account linking.

However, for security reasons, a client shouldn't send profile information such as a user ID to a server as the basis for user authentication. This article explains the basic approach to securely identifying users on your server.

Profile information sent by a client can be tampered with

For example, you can use liff.getProfile() to get the user's ID, display name, and other information in a LIFF app. You can use this information to show the user's profile in the LIFF app's UI.

However, the following implementation, which sends the retrieved information to the server and treats userId as the logged-in user, isn't secure:

javascript
// Incorrect example: Send a user ID to the server
const profile = await liff.getProfile();

await fetch("/api/login", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    userId: profile.userId,
    displayName: profile.displayName,
  }),
});

Users can modify code running in a browser or app and the requests sent by that code. If an attacker replaces the userId in the request with a different value, the server has no way to determine whether that value came from the LINE Platform. Using only this value for login or account linking could allow an attacker to impersonate another user.

The following sequence diagram shows how an attacker who knows another user's user ID can impersonate that user by replacing the userId.

Suppose an attacker somehow obtains another user's user ID and replaces the userId in a login request with that value. If the server issues a session without verifying the value, the attacker could log in as that user, view their account information or reservation history, or fraudulently use their points or coupons. A user ID isn't a password and can't be used by itself to verify a user's identity.

For the same reason, don't send profile information obtained with liff.getDecodedIDToken() to your server for user authentication.

Send the raw token and verify it on the server

To identify a user on your server, send a raw ID token or access token from the client instead of a user ID. The server then calls a LINE Platform API to verify the token and gets the user ID from the verification result.

The following sequence diagram shows the overall flow when using an ID token.

The important point is that the LIFF app sends the raw ID token, not profile information, to your service's server, and the server uses the verification result received directly from the LINE Platform. The specific steps are as follows:

  1. After liff.init() completes, call liff.getIDToken() in the LIFF app to get the raw ID token
  2. Send the ID token to your service's server over HTTPS
  3. From the server, send the ID token and expected channel ID to the Verify ID token endpoint
  4. Treat the sub in a successful verification response as the LINE user ID
javascript
const idToken = liff.getIDToken();
if (!idToken) {
  throw new Error("ID token is unavailable");
}

await fetch("/api/login", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ idToken }),
});

When integrating LINE Login into a web app, the backend normally sends the authorization code returned to the callback URL to the LINE Platform's token endpoint. The backend then gets an access token and, if the openid scope was specified, an ID token. In this case, identify the user from the token obtained and verified by the backend, instead of using a user ID sent from the browser.

You can also use an access token. On your server, call the Verify access token validity endpoint and confirm that the client_id in the verification result matches the expected channel ID and that expires_in is a positive value. Then get the user ID from the Get user profile endpoint.

Exchange the verified token for your service's session

After getting the verified user ID, issue a session for your service. Use that session to manage the user's login state in subsequent requests.

  1. For a LIFF app, send the ID token or access token to your service's server. For LINE Login integrated into a web app, the backend exchanges the authorization code for tokens
  2. Call a LINE Platform API from your service's server to verify the token
  3. Get the user ID from the verification result
  4. Issue a session for your service based on the obtained user ID

Avoid using a token from the LINE Platform as a long-lived session for your service. In particular, an access token obtained by a LIFF app may be revoked when the user closes the LIFF app. Therefore, implementations that save the token to localStorage or a similar location and reuse it the next time the app is opened can cause authentication to fail unexpectedly.

ID tokens and access tokens are credentials. Send them over HTTPS, and don't record them in logs or analytics tools. If you use cookies to manage sessions for your service, protect the session itself appropriately, such as by setting the Secure and HttpOnly attributes.

Choose the right data for each purpose

The same user information must be handled differently on the client and the server.

PurposeInformation to use
Show a display name or profile image in the LIFF app's UIInformation obtained with liff.getProfile() or liff.getDecodedIDToken()
Identify a user on the serverThe result of verifying a raw token obtained with liff.getIDToken() or liff.getAccessToken() on the server
Maintain login state after verificationA session issued by your service

Wrap-up

Profile information obtained on a client can be displayed to the end user, but it can be tampered with. Therefore, using it as is as the basis for user authentication on the server is unsafe. To identify a user on your server, receive a raw ID token or access token and use the result of verifying it with the LINE Platform.

For more information, see Using user data in LIFF apps and servers in the LIFF documentation and LINE Login security checklist in the LINE Login documentation.