# Implement discourse Apple login using API

**URL:** https://meta.discourse.org/t/implement-discourse-apple-login-using-api/286700
**Category:** Development
**Tags:** apple-auth
**Created:** [November 27, 2023, 8:49am UTC](https://meta.discourse.org/t/implement-discourse-apple-login-using-api/286700 "2023-11-27T08:49:50Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![wings](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wings/32/331381_2.png) [@wings](https://meta.discourse.org/u/wings)
#### Post date: [November 27, 2023, 8:49am UTC](https://meta.discourse.org/t/implement-discourse-apple-login-using-api/286700/1 "2023-11-27T08:49:50Z")

</div>

Hi, I am working on building an API for Discourse login using Apple. I have already installed the plugin and followed the instructions from [Discourse Apple Authentication](https://meta.discourse.org/t/discourse-apple-authentication/171485). It works fine when logging into Discourse using an Apple account in website.

Upon checking the flow of Apple login from the web, I noticed that it redirects to the Apple page for login, obtains a code generated from Apple upon successful login, and then redirects to:

POST `{{discourse_host}}/auth/apple/callback` with parameters `state:{state}, code:{code from Apple}`

After that, it redirects to GET `{{discourse_host}}/auth/apple/callback?code={{code from Apple}}&state={state}`, generating a new cookie that will be used in the Discourse API.

 ![image](https://global.discourse-cdn.com/meta/original/4X/8/6/5/86568e507ad1e5c938b8eae417b6d3e600e02470.png)

from this flow I expect it will generate a new cookie after the call `/auth/apple/callback`

But when I try to call the API it will show the error `Authorization timed out, or you have switched browsers. Please try again.`

 ![image](https://global.discourse-cdn.com/meta/original/4X/9/f/8/9f861776c1ecb7552f3635e49db3ee2ef0fcfa3b.png)

So I tried again with a new code generated by Apple but still got the same error

And when I check the log it show

```plaintext
Started GET "/auth/apple/callback?code=c32f105b5084d42b8bd3e7051873ddb55.0.rrzxz.pChPU9zGlXIHHhgEXLiA5g&state=fbi3bbboud" for>
(apple) Setup endpoint detected, running now.
(apple) Callback phase initiated.
(apple) Authentication failure! csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF detected
Started GET "/auth/failure?message=csrf_detected&strategy=apple" for 123.253.233.16 at 2023-11-27 06:10:28 +0000
Processing by Users::OmniauthCallbacksController#failure as HTML
  Parameters: {"message"=>"csrf_detected", "strategy"=>"apple"}
  Rendered users/omniauth_callbacks/failure.html.erb within layouts/no_ember (Duration: 4.1ms | Allocations: 17)
  Rendered layout layouts/no_ember.html.erb (Duration: 57.5ms | Allocations: 2882)

```

 ![image](https://global.discourse-cdn.com/meta/original/4X/5/b/9/5b9d4e8aa7d0ac1a27e29c5acfd07223223a35bc.png)

```plaintext
Message (47 copies reported)

(apple) Authentication failure! csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF detected

Backtrace

/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:163:in `log'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:486:in `fail!'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-oauth2-1.7.3/lib/omniauth/strategies/oauth2.rb:87:in `callback_phase'
/var/www/discourse/plugins/discourse-apple-auth/lib/omniauth_apple.rb:60:in `callback_phase'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:238:in `callback_call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:189:in `call!'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:192:in `call!'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:192:in `call!'

```

So I want to ask if this direction to using discourse apple sign-in using API is already correct and how I solve the problem with csrf\_detected error

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [November 27, 2023, 10:00am UTC](https://meta.discourse.org/t/implement-discourse-apple-login-using-api/286700/2 "2023-11-27T10:00:59Z")

</div>

The Apple authentication (and indeed, all other auth methods in DIscourse) are not designed to be used via the API. They should be used directly be end-users in a supported browser.

What problem are you trying to solve here? Perhaps we can work out an alternative solution?

---

<div class="post-metadata">

### Author: ![wings](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wings/32/331381_2.png) [@wings](https://meta.discourse.org/u/wings)
#### Post date: [November 27, 2023, 12:15pm UTC](https://meta.discourse.org/t/implement-discourse-apple-login-using-api/286700/3 "2023-11-27T12:15:41Z")

</div>

Hi @david, thanks for your reply. What I want to achieve here is to create an API for Apple login that will be used by the mobile app to access the Discourse API.

For using the Discourse API to log in with email and password, it works fine using these two Discourse APIs:

1. `{{discourse_host}}/session/csrf.json`: This API returns a cookie and CSRF code, which will be used for login using the next API.
2. `{{discourse_host}}/session`: This API returns a new cookie that can be used to access other Discourse APIs.

> **Csrf API**
>
> ![image](https://global.discourse-cdn.com/meta/original/4X/d/a/5/da55f476e17010098bbc4637c58763731ab737ef.png)
> 
> ![image](https://global.discourse-cdn.com/meta/original/4X/b/f/5/bf58000b7bb7f7394559870ff78d7e71455124c5.png)

> **Session**
>
> ![image](https://global.discourse-cdn.com/meta/original/4X/0/7/3/073a4739ec6eb0a6b02b0c5a404750b1e259e2fd.png)

I expect it to be similar to Apple login in Discourse, where I make a request to the Discourse API to generate the `_t` cookie.

---

<div class="post-metadata">

### Author: ![wings](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wings/32/331381_2.png) [@wings](https://meta.discourse.org/u/wings)
#### Post date: [December 4, 2023, 3:16am UTC](https://meta.discourse.org/t/implement-discourse-apple-login-using-api/286700/4 "2023-12-04T03:16:15Z")

</div>

Hi @david, do you have a solution for my issue?

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [December 4, 2023, 10:49am UTC](https://meta.discourse.org/t/implement-discourse-apple-login-using-api/286700/5 "2023-12-04T10:49:21Z")

</div>

I’m afraid there’s no easy answer. Authentication APIs like this are specifically designed to avoid them being triggered without real user interaction on the web.

For your use case, the more common solution would be to use the [user API keys](https://meta.discourse.org/t/user-api-keys-specification/48536) system. That will allow Discourse to handle 100% of the authentication logic, and will give your app some per-user API keys. That strategy should be much more robust than trying to ‘fake’ a user session.
