First Time Implementing OAuth On X: Thoughts
Tags: oauth, kotlin
Published: 2024-05-22 00:26:30

After 7 years of development, I have never tried OAuth 1.0 or 2.0. But in the next micro-SaaS I am creating, users will have the option to log in with X. I don't want to add other options for two reasons.

The first is that I like Elon a lot and want to support his platform the best way possible. The second is that when you have multiple login options, sometimes you don't remember which one you used and this has happed a lot to me over the years.

## Pre-cooked options

I know that there are options like auth0 but because I want to learn how OAuth works and how the infrastructure is working I decided to implement the whole authentication process myself.

I am using a Kotlin API that has a regular authentication process with JWT. On top of JWT, I want, when the user log in with X, to get their avatar and username and create an account on my application if it does not exist.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kcrmxwn14gj5eowxpmlz.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdzzvhxuurhuugrixrwr.png)

## How OAuth Works

OAuth is basically a 3-step process. You can read the full documentation on [X API Docs](https://developer.x.com/en/docs/authentication/guides/log-in-with-twitter), but I will cover it briefly to help you understand the process better.

Also keep in mind that OAuth is something like a protocol the process is basically the same in every platform you use with minor differences.

**Prerequisites**

Each request has some specific headers. Which include the following values:

* oauth\_consumer\_key Identifies the application requesting access (get it from [developer portal](https://developer.twitter.com/en/portal/dashboard)).
    
* oauth\_nonce (A unique, randomly generated value used to prevent replay attacks - unique token.)
    
* oauth\_signature (The signature of the request (a cryptographic code ensuring request authenticity create by the other values)
    
* oauth\_signature\_method (The method used to generate the signature e.g., HMAC-SHA1).
    
* oauth\_timestamp (The current time in seconds to prevent replay attacks).
    
* oauth\_version (The OAuth version used e.g., OAuth 1.0).
    

Before I go in more detail, here is a visual representation of how oauth works in my workflow with X.




**1st Step**

The first step is to get a request token from the X API. That token will help us continue with the other requests

```kotlin
fun requestToken(): String? {
        val client = OkHttpClient()
        val mediaType = "text/plain".toMediaType()
        val body = "".toRequestBody(mediaType)
        val request = Request.Builder()
            .url("https://api.twitter.com/oauth/request_token")
            .post(body)
            .addHeader(
                "Authorization",
                "OAuth oauth_consumer_key=\"KEY\",oauth_signature_method=\"HMAC-SHA1\",oauth_timestamp=\"1716307731\",oauth_nonce=\"NONCE\",oauth_version=\"1.0\",oauth_signature=\"SIGNATURE\""
            )
            .build()
        val response = client.newCall(request).execute()
        val responseString = response.body?.string()
        val oauthToken = responseString?.substringAfter("oauth_token=")?.substringBefore("&")
        return oauthToken
    }
```

**2nd Step**

After we have the request token now we can get the verifier from the authorize request.

```kotlin
    @GetMapping("/x/login-redirect")
    fun loginRedirect(): RedirectView {
        val oauthToken = xService.requestToken()
        val redirectView = RedirectView()
        redirectView.url = "https://api.twitter.com/oauth/authorize?oauth_token=$oauthToken"

        return redirectView
    }
```

**3rd Step**

The last step is to get the Token with the Secret so we can then move on on getting the user data and finishing our authentication.

Keep in mind the callback is the request the X Api redirect back to when we finish step 2. As a parameter it has the verifier token.

```kotlin
    @GetMapping("/x/callback")
    fun oauth2Callback(
        @RequestParam("oauth_token") oauthToken: String,
        @RequestParam("oauth_verifier") oauthVerifier: String
    ): XCallbackResponse {
        val oauthToken = xService.accessToken(oauthVerifier, oauthToken)

        if (oauthToken.token === "error") {
            throw IllegalStateException("Token is null")
        }
        // your other code
    }
```

Now with everything finished, we have full access to X's API for the specific user who logged in.

## Implementation

As an implementation, it is not very simple; rather, I would say it is complex and difficult. This is why we have OAuth2, which we are going to cover in another article, and it is a lot simpler to understand and implement.

Also, with Kotlin or Spring Boot, there are many libraries you can use that handle the implementation with minimal code by using the default Spring Boot Security Config.

## Use Cases

The question is whether it is worth adding OAuth to your application. In my opinion, it is only necessary for B2C products. If you have a B2B application with few daily active users, you don't need to use it.

However, for applications with many users, making the login process simple and fast is very important. If you don't want to add X, you can also try Google, which has a very similar process.

## Final Words

Implementing OAuth for the first time can be a challenging but rewarding experience. By choosing to integrate X as your authentication provider, you not only streamline the login process for your users but also gain valuable insights into how OAuth works under the hood.

While the process may seem complex initially, understanding each step and its significance can demystify OAuth and make it more manageable. With this knowledge, you're better equipped to build secure and user-friendly authentication systems for your future projects.

Thanks for reading, and I hope you found this article helpful. If you have any questions, feel free to email me at [**kourouklis@pm.me**](mailto:kourouklis@pm.me)**, and I will respond.**

You can also keep up with my latest updates by checking out my X here: [**x.com/sotergreco**](http://x.com/sotergreco)