{"id":5953,"date":"2021-01-11T11:58:40","date_gmt":"2021-01-11T11:58:40","guid":{"rendered":"https:\/\/uhp.digital\/?p=5953"},"modified":"2021-01-11T12:33:33","modified_gmt":"2021-01-11T12:33:33","slug":"wie-man-sign-in-with-apple-implementiert","status":"publish","type":"post","link":"https:\/\/uhp.digital\/en\/blog\/wie-man-sign-in-with-apple-implementiert\/","title":{"rendered":"How to Implement Sign in With Apple Authentication in Symfony"},"content":{"rendered":"<p>Like Google, Apple introduced an authentication system called <strong>Sign in With Apple<\/strong> .<\/p>\n\n\n\n<p>This means that users who have Apple ID can sign in or login to a web or an app service using their existing credentials.<\/p>\n\n\n\n<p>This article will help you to understand and implement Sign in With Apple feature into your Symfony application.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Who is this article for?<\/strong><\/h4>\n\n\n\n<p>This article is useful for PHP backend developers. It has been written for Symfony framework but it can be used for other frameworks as well (with some changes).<\/p>\n\n\n\n<p>This article is not for beginners and will not explain the basic setup of Symfony. To know more about Symfony, you can find the Symfony documentation <a href=\"https:\/\/symfony.com\/doc\/current\/getting_started\/index.html\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<p>If you would like to follow this tutorial, some previous knowledge is required. More specifically, we are talking about the knowledge of:<\/p>\n\n\n\n<p>1. PHP OOP<\/p>\n\n\n\n<p>2. Symfony<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Benefits of the Apple Sign in authentication<\/strong><\/h4>\n\n\n\n<p>Apart from using the existing login service provider UI, users now have an option to \"privately\" sign in to a service.<\/p>\n\n\n\n<p>What that means is that Apple will hide real user email and generate a new one that will need to be used in a service.<\/p>\n\n\n\n<p>This will also prevent trackers from other platforms to track what kind of apps or services you are using.<\/p>\n\n\n\n<p>If you are using an Apple device, sign in can be achieved via Touch ID or Face ID that is a quicker way of signing in.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Is Sign in with Apple mandatory?<\/strong><\/h4>\n\n\n\n<p>If you're dealing with an API that requires an authentication of iOS devices, then the answer is yes.<\/p>\n\n\n\n<p>At this point, Apple is forcing their new or existing apps that have any kind of a \u201esign in\u201c feature to also implement Sign in with Apple.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>How Sign In with Apple works:<\/strong><\/h4>\n\n\n\n<p>The server side authentication is very easy to understand as most of the job is on the Client App side. \nClient App (mobile or frontend app) will connect to an Apple server and will send the user's email and password. In this step, the user will be asked if he would like to hide his email.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"472\" height=\"1024\" src=\"https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/APPLE-472x1024.png\" alt=\"\" class=\"wp-image-5954\" srcset=\"https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/APPLE-472x1024.png 472w, https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/APPLE-138x300.png 138w, https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/APPLE-6x12.png 6w, https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/APPLE.png 484w\" sizes=\"(max-width: 472px) 100vw, 472px\" \/><\/figure>\n\n\n\n<p>Apple will then return the user data to the Client App and that data will be sent to the Server. The most important thing here is the <strong>authorization_code<\/strong>. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"961\" height=\"540\" src=\"https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/APP2.png\" alt=\"\" class=\"wp-image-5955\" srcset=\"https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/APP2.png 961w, https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/APP2-300x169.png 300w, https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/APP2-768x432.png 768w, https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/APP2-16x9.png 16w\" sizes=\"(max-width: 961px) 100vw, 961px\" \/><\/figure>\n\n\n\n<p>What the server is actually doing is verifying that the authotization_code is valid and that the user exists. <\/p>\n\n\n\n<p>Since the user can hide his email, we need to be aware that we will not get the user's real data -  except in the case when the real data is neccessery and we ask the user that later.<\/p>\n\n\n\n<p>Steps:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>App will send us an authorization_code on the backend server<\/li><li>Backend server will make a request to an Apple server<\/li><li>Apple server will return a response<\/li><\/ol>\n\n\n\n<p>Requirements:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>The credentials from the Apple Connect: Apple Connect is an Apple service for handling iOS apps. There, we can get all the credentials that are needed for telling Apple that we are authorized to check users authorization_code.<\/li><li>Save Apple ID \u2013 this  is needed to find user for login.<\/li><li>patrickbussamann\/oauth2-apple  -  library that will handle most of the logic for us<\/li><\/ul>\n\n\n\n<p>NOTICE!<\/p>\n\n\n\n<p>You will get the user email only upon registration, later during login only the ID will be shown in response. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Apple Credentials and where to find them<\/strong><\/h4>\n\n\n\n<p>The credentials can be found on Apple Cloud Account but from the backend developers side, usually you can just ask someone from the mobile department to give you those. Otherwise, if you have access to the App Store Connect for the app, you can find the credentials under your app settings.<\/p>\n\n\n\n<p>You will need the following:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Apple Key ID <a href=\"https:\/\/developer.apple.com\/account\/resources\/authkeys\/list\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/developer.apple.com\/account\/resources\/authkeys\/list<\/a><\/li><li>Apple Team ID <a href=\"https:\/\/developer.apple.com\/account\/#\/membership\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/developer.apple.com\/account\/#\/membership\/ <\/a><\/li><li>Apple Client ID \u2013 This is your client ID<\/li><li>Key File Path -&gt; you will need to download file on <a href=\"https:\/\/developer.apple.com\/account\/resources\/authkeys\/list\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/developer.apple.com\/account\/resources\/authkeys\/list<\/a> and set path to this file<\/li><\/ol>\n\n\n\n<p>It is important that you enable Sign in with Apple under <em>Certificates, Identifiers &amp; Profiles<\/em> . <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"31\" src=\"https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/app3-1024x31.png\" alt=\"\" class=\"wp-image-5956\" srcset=\"https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/app3-1024x31.png 1024w, https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/app3-300x9.png 300w, https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/app3-768x23.png 768w, https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/app3-16x1.png 16w, https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/app3.png 1448w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>We have put the credentials for our app in .env file of our project: <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"944\" height=\"162\" src=\"https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/app4.png\" alt=\"\" class=\"wp-image-5957\" srcset=\"https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/app4.png 944w, https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/app4-300x51.png 300w, https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/app4-768x132.png 768w, https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/app4-16x3.png 16w\" sizes=\"(max-width: 944px) 100vw, 944px\" \/><\/figure>\n\n\n\n<p>Adding Apple ID to the database is pretty simple in Symphony. If you are using a classic MVC architecture just use <em>maker<\/em> and add that field to an Entity (usually on User entity but if you have another Entity where you store that kind of data, that\u2019s ok).<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Installing oauth2-apple library to app:<\/strong><\/h4>\n\n\n\n<p>This requires only one step:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Type composer require patrickbussamann\/oauth2-apple in your terminal<\/li><\/ol>\n\n\n\n<p>This will install a package that contains everything you need to verify with the user authorization code.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Implementation of the PHP part<\/strong><\/h4>\n\n\n\n<p>We are using Factory method pattern here. To find out more about this design pattern,<a href=\"https:\/\/refactoring.guru\/design-patterns\/factory-method\/php\/example#:~:text=Factory%20method%20is%20a%20creational,constructor%20call%20(%20new%20operator).\" target=\"_blank\" rel=\"noreferrer noopener\"> <\/a>follow this<a href=\"https:\/\/refactoring.guru\/design-patterns\/factory-method\/php\/example#:~:text=Factory%20method%20is%20a%20creational,constructor%20call%20(%20new%20operator).\" target=\"_blank\" rel=\"noreferrer noopener\"> link<\/a>.<\/p>\n\n\n\n<p>In Factory, we will create our provider that will handle the request for us.\nIn this part, we will need to pass  the Apple Credentials to the constructor of the provider. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">class AppleProviderFactory\n{\n    private const FILE_CREDENTIALS_PATH = 'path\/to\/key\/file;\n\n    \/**\n     * @param string $clientId\n     * @param string $teamId\n     * @param string $keyFileId\n     * @param string $redirectUrl\n     * @return Apple\n     * @throws Exception\n     *\/\n    public static function createProvider(\n        string $clientId,\n        string $teamId,\n        string $keyFileId,\n        string $redirectUrl\n    ): Apple {\n        return  new Apple([\n            'clientId'          =&gt; $clientId,\n            'teamId'            =&gt; $teamId, \/\/https:\/\/developer.apple.com\/account\/#\/membership\/ (Team ID)\n            'keyFileId'         =&gt; $keyFileId, \/\/https:\/\/developer.apple.com\/account\/resources\/authkeys\/list (Key ID)\n            'keyFilePath'       =&gt; self::FILE_CREDENTIALS_PATH, \/\/__DIR__ . '\/AuthKey_template.p8'-&gt;Download key above\n            'redirectUri'      =&gt; $redirectUrl \/\/The destination URI the code was originally sent to.\n        ]);\n    }\n}\n<\/pre>\n\n\n\n<p>Apple Authenticator is our class that will hold the logic of getting users' data.<\/p>\n\n\n\n<p>It is important to wrap logic in \u201etry catch\u201c method and handle errors ourselves.<\/p>\n\n\n\n<p>If verification fails, you will get an Apple response code that you can google and find the solution to.&nbsp;&nbsp;<\/p>\n\n\n\n<p><strong>The most problematic part is that the authorization_code has a time frame and it can be used only one time so it is good to have an iOS or a Frontend dev on stand-by when you will be implementing this.<\/strong> <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><em>class <\/em>AppleAuthenticator<br>{<br>&nbsp;&nbsp;&nbsp; <em>private const <\/em>AUTHORIZATION_CODE_NAME_REFERENCE = 'authorization_code';<br>&nbsp;&nbsp;&nbsp; <em>private const <\/em>CODE_NAME_REFERENCE = 'code';<br>&nbsp;&nbsp;&nbsp; <em>\/**<br>&nbsp;&nbsp;&nbsp;&nbsp; * <\/em><strong><em>@var <\/em><\/strong><em>Apple<br>&nbsp;&nbsp;&nbsp;&nbsp; <\/em><em>*\/<br>&nbsp;&nbsp;&nbsp; <\/em><em>private <\/em>Apple $provider;<br><br>&nbsp;&nbsp;&nbsp; <em>\/**<br>&nbsp;&nbsp;&nbsp;&nbsp; * AppleAuthenticator constructor.<br>&nbsp;&nbsp;&nbsp;&nbsp; * <\/em><strong><em>@param <\/em><\/strong><em>Apple <\/em><em>$provider<br>&nbsp;&nbsp;&nbsp;&nbsp; *\/<br>&nbsp;&nbsp;&nbsp; <\/em><em>public<\/em><em> function <\/em>__construct(Apple $provider)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;provider = $provider;<br>&nbsp;&nbsp;&nbsp; }<br><br><br>&nbsp;&nbsp;&nbsp; <em>\/**<br>&nbsp;&nbsp;&nbsp;&nbsp; * <\/em><strong><em>@param <\/em><\/strong><em>string <\/em><em>$authorisationCode<br>&nbsp;&nbsp;&nbsp;&nbsp; * <\/em><strong><em>@return <\/em><\/strong><em>ResourceOwnerInterface<br>&nbsp;&nbsp;&nbsp;&nbsp; <\/em><em>* <\/em><strong><em>@throws <\/em><\/strong><em>AppleServerException<br>&nbsp;&nbsp;&nbsp;&nbsp; <\/em><em>*\/<br>&nbsp;&nbsp;&nbsp; <\/em><em>public function <\/em>getUserData(<em>string <\/em>$authorisationCode): ResourceOwnerInterface<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>try <\/em>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>\/** <\/em><strong><em>@var <\/em><\/strong><em>AccessToken <\/em><em>$token <\/em><em>*\/<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/em>$token = $this-&gt;provider-&gt;getAccessToken(<em>self<\/em>::AUTHORIZATION_CODE_NAME_REFERENCE, [<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>self<\/em>::CODE_NAME_REFERENCE =&gt; $authorisationCode<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ]);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $user = $this-&gt;provider-&gt;getResourceOwner($token);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <em>catch <\/em>(Exception $exception) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>throw new <\/em>AppleServerException($exception);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>return <\/em>$user;<br>&nbsp;&nbsp;&nbsp; }<br>}<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"><em>class <\/em>AppleAuthenticationService<br>{<br>&nbsp;&nbsp;&nbsp; <em>\/**<br>&nbsp;&nbsp;&nbsp;&nbsp; * <\/em><strong><em>@var <\/em><\/strong><em>string<br>&nbsp;&nbsp;&nbsp;&nbsp; *\/<br>&nbsp;&nbsp;&nbsp; private string <\/em>$clientId;<br><br>&nbsp;&nbsp;&nbsp; <em>\/**<br>&nbsp;&nbsp;&nbsp;&nbsp; * <\/em><strong><em>@var <\/em><\/strong><em>string<br>&nbsp;&nbsp;&nbsp;&nbsp; *\/<br>&nbsp;&nbsp;&nbsp; private string <\/em>$teamId;<br><br>&nbsp;&nbsp;&nbsp; <em>\/**<br>&nbsp;&nbsp;&nbsp;&nbsp; * <\/em><strong><em>@var <\/em><\/strong><em>string<br>&nbsp;&nbsp;&nbsp;&nbsp; *\/<br>&nbsp;&nbsp;&nbsp; private string <\/em>$appleKeyId;<br><br>&nbsp;&nbsp;&nbsp; <em>\/**<br>&nbsp;&nbsp;&nbsp;&nbsp; * AuthenticationService constructor.<br>&nbsp;&nbsp;&nbsp;&nbsp; * <\/em><strong><em>@param <\/em><\/strong><em>string $clientId<br>&nbsp;&nbsp;&nbsp;&nbsp; * <\/em><strong><em>@param <\/em><\/strong><em>string $teamId<br>&nbsp;&nbsp;&nbsp;&nbsp; * <\/em><strong><em>@param <\/em><\/strong><em>string $appleKeyId<br>&nbsp;&nbsp;&nbsp;&nbsp; *\/<br>&nbsp;&nbsp;&nbsp; public function <\/em>__construct(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>string <\/em>$clientId,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>string <\/em>$teamId,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>string <\/em>$appleKeyId<br>&nbsp;&nbsp;&nbsp; ) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;clientId = $clientId;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;teamId = $teamId;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;appleKeyId = $appleKeyId;<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; <em>\/**<br>&nbsp;&nbsp;&nbsp;&nbsp; * <\/em><strong><em>@param <\/em><\/strong><em>string $authorizationCode<br>&nbsp;&nbsp;&nbsp;&nbsp; * <\/em><strong><em>@param <\/em><\/strong><em>string $redirectUrl<br>&nbsp;&nbsp;&nbsp;&nbsp; * <\/em><strong><em>@return <\/em><\/strong><em>ResourceOwnerInterface<br>&nbsp;&nbsp;&nbsp;&nbsp; * <\/em><strong><em>@throws <\/em><\/strong><em>AppleServerException<br>&nbsp;&nbsp;&nbsp;&nbsp; *\/<br>&nbsp;&nbsp;&nbsp; public function <\/em>authenticate(<em>string <\/em>$authorizationCode, <em>string <\/em>$redirectUrl): ResourceOwnerInterface<br>&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/create provider<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $applePrpvider = AppleProviderFactory::<em>createProvider<\/em>(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;clientId,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;teamId,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;keyFileId,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $redirectUrl<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/\/ pass provider and authorization_code to Authenticator and get users data<br><br><\/pre>\n\n\n\n<p>In your handler, with the autowiring, you can access the authentication service like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><em>\/**<br>\n&nbsp;* <\/em><strong><em>@var <\/em><\/strong><em>AppleAuthenticationService<br>\n&nbsp;<\/em><em>*\/<br>\n<\/em><em>private <\/em>AppleAuthenticationService $authenticationService;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"><em>\/**\n\n&nbsp;* CreateAppleUserHandler constructor.\n\n&nbsp;* <\/em><strong><em>@param <\/em><\/strong><em>AppleAuthenticationService $authenticationService\n\n&nbsp;*\/\n\npublic function <\/em>__construct(\n\n&nbsp;&nbsp;&nbsp; AppleAuthenticationService $authenticationService\n\n) {\n\n&nbsp;&nbsp;&nbsp; $this-&gt;authenticationService = $authenticationService;\n\n} <\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">$user = $this-&gt;authenticationService-&gt;authenticate(<br>&nbsp;&nbsp;&nbsp; 'auth_code'<br>&nbsp;&nbsp;&nbsp; 'redirect_url'<br>);<\/pre>\n\n\n\n<p>To handle  the Sign in and login a bit easier, we choose to return to the user our JWT authentication token on response.&nbsp;&nbsp;<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Conclusion<\/h4>\n\n\n\n<p>Sign in With Apple is a secure and a fast way for iOS users to register and use services that require authentication.<\/p>\n\n\n\n<p>The assumption is that, as time passes, it will be normal to see it alongside with the web Google and Facebook login.<\/p>\n\n\n\n<p>It is fairly easy to implement this once you get the idea of how it works.<\/p>\n\n\n\n<p>This article has explained how all this works step-by-step, so everything should work for you, just remember this:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Email can be private<\/li><li>Email will be shown only the first time<\/li><li>Authorization_code has a timeframe of working<\/li><\/ol>\n\n\n\n<p>Happy coding!<\/p>","protected":false},"excerpt":{"rendered":"<p>Brauchen Sie Hilfe bei der Implementierung von Apples neuer Funktion &#8222;Sign in with Apple&#8220;?<br \/>\nUnsere Entwickler haben eine Schritt-f\u00fcr-Schritt-Anleitung vorbereitet, wie es geht.<br \/>\nWenn Sie mehr \u00fcber diese neue Funktion erfahren und neue F\u00e4higkeiten erlernen m\u00f6chten, lesen Sie unseren neuen Blog-Beitrag. <\/p>","protected":false},"author":1,"featured_media":5960,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"template-parts\/single-post-template.php","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[13],"tags":[],"class_list":["post-5953","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tech"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Wie man &quot;Sign in With Apple&quot; Authentication in Symfony implementiert - UHP<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/uhp.digital\/en\/blog\/wie-man-sign-in-with-apple-implementiert\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Wie man &quot;Sign in With Apple&quot; Authentication in Symfony implementiert - UHP\" \/>\n<meta property=\"og:description\" content=\"Brauchen Sie Hilfe bei der Implementierung von Apples neuer Funktion &quot;Sign in with Apple&quot;? Unsere Entwickler haben eine Schritt-f\u00fcr-Schritt-Anleitung vorbereitet, wie es geht. Wenn Sie mehr \u00fcber diese neue Funktion erfahren und neue F\u00e4higkeiten erlernen m\u00f6chten, lesen Sie unseren neuen Blog-Beitrag.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/uhp.digital\/en\/blog\/wie-man-sign-in-with-apple-implementiert\/\" \/>\n<meta property=\"og:site_name\" content=\"UHP\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/uhpdigital\/\" \/>\n<meta property=\"article:published_time\" content=\"2021-01-11T11:58:40+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-01-11T12:33:33+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/uhp.digital\/wp-content\/uploads\/2020\/02\/FB-Logo@3x.png\" \/>\n\t<meta property=\"og:image:width\" content=\"540\" \/>\n\t<meta property=\"og:image:height\" content=\"540\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"UHP\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"UHP\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/\"},\"author\":{\"name\":\"UHP\",\"@id\":\"https:\/\/uhp.digital\/#\/schema\/person\/82c263f7a03b60653db3cdd2d4301acb\"},\"headline\":\"Wie man &#8222;Sign in With Apple&#8220; Authentication in Symfony implementiert\",\"datePublished\":\"2021-01-11T11:58:40+00:00\",\"dateModified\":\"2021-01-11T12:33:33+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/\"},\"wordCount\":1091,\"publisher\":{\"@id\":\"https:\/\/uhp.digital\/#organization\"},\"image\":{\"@id\":\"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/img-sign-in.svg\",\"articleSection\":[\"Tech\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/\",\"url\":\"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/\",\"name\":\"Wie man \\\"Sign in With Apple\\\" Authentication in Symfony implementiert - UHP\",\"isPartOf\":{\"@id\":\"https:\/\/uhp.digital\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/img-sign-in.svg\",\"datePublished\":\"2021-01-11T11:58:40+00:00\",\"dateModified\":\"2021-01-11T12:33:33+00:00\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/#primaryimage\",\"url\":\"https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/img-sign-in.svg\",\"contentUrl\":\"https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/img-sign-in.svg\",\"width\":636,\"height\":484},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/uhp.digital\/#website\",\"url\":\"https:\/\/uhp.digital\/\",\"name\":\"UHP\",\"description\":\"Delivering digital impact.\",\"publisher\":{\"@id\":\"https:\/\/uhp.digital\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/uhp.digital\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/uhp.digital\/#organization\",\"name\":\"UHP\",\"url\":\"https:\/\/uhp.digital\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/uhp.digital\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/uhp.digital\/wp-content\/uploads\/2020\/01\/uhp-logo.svg\",\"contentUrl\":\"https:\/\/uhp.digital\/wp-content\/uploads\/2020\/01\/uhp-logo.svg\",\"width\":88,\"height\":40,\"caption\":\"UHP\"},\"image\":{\"@id\":\"https:\/\/uhp.digital\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/uhpdigital\/\",\"https:\/\/www.instagram.com\/uhpdigital\/\",\"https:\/\/www.linkedin.com\/company\/uhp-software\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/uhp.digital\/#\/schema\/person\/82c263f7a03b60653db3cdd2d4301acb\",\"name\":\"UHP\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/uhp.digital\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/c1bc770aea92efb4d58edb8d8e86f9eaa06def97a45852ce534799e57534d6c6?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/c1bc770aea92efb4d58edb8d8e86f9eaa06def97a45852ce534799e57534d6c6?s=96&d=mm&r=g\",\"caption\":\"UHP\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to Implement Sign in With Apple Authentication in Symfony - UHP","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/uhp.digital\/en\/blog\/wie-man-sign-in-with-apple-implementiert\/","og_locale":"en_US","og_type":"article","og_title":"Wie man \"Sign in With Apple\" Authentication in Symfony implementiert - UHP","og_description":"Brauchen Sie Hilfe bei der Implementierung von Apples neuer Funktion \"Sign in with Apple\"? Unsere Entwickler haben eine Schritt-f\u00fcr-Schritt-Anleitung vorbereitet, wie es geht. Wenn Sie mehr \u00fcber diese neue Funktion erfahren und neue F\u00e4higkeiten erlernen m\u00f6chten, lesen Sie unseren neuen Blog-Beitrag.","og_url":"https:\/\/uhp.digital\/en\/blog\/wie-man-sign-in-with-apple-implementiert\/","og_site_name":"UHP","article_publisher":"https:\/\/www.facebook.com\/uhpdigital\/","article_published_time":"2021-01-11T11:58:40+00:00","article_modified_time":"2021-01-11T12:33:33+00:00","og_image":[{"width":540,"height":540,"url":"https:\/\/uhp.digital\/wp-content\/uploads\/2020\/02\/FB-Logo@3x.png","type":"image\/png"}],"author":"UHP","twitter_card":"summary_large_image","twitter_misc":{"Written by":"UHP","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/#article","isPartOf":{"@id":"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/"},"author":{"name":"UHP","@id":"https:\/\/uhp.digital\/#\/schema\/person\/82c263f7a03b60653db3cdd2d4301acb"},"headline":"Wie man &#8222;Sign in With Apple&#8220; Authentication in Symfony implementiert","datePublished":"2021-01-11T11:58:40+00:00","dateModified":"2021-01-11T12:33:33+00:00","mainEntityOfPage":{"@id":"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/"},"wordCount":1091,"publisher":{"@id":"https:\/\/uhp.digital\/#organization"},"image":{"@id":"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/#primaryimage"},"thumbnailUrl":"https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/img-sign-in.svg","articleSection":["Tech"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/","url":"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/","name":"How to Implement Sign in With Apple Authentication in Symfony - UHP","isPartOf":{"@id":"https:\/\/uhp.digital\/#website"},"primaryImageOfPage":{"@id":"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/#primaryimage"},"image":{"@id":"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/#primaryimage"},"thumbnailUrl":"https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/img-sign-in.svg","datePublished":"2021-01-11T11:58:40+00:00","dateModified":"2021-01-11T12:33:33+00:00","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/uhp.digital\/blog\/wie-man-sign-in-with-apple-implementiert\/#primaryimage","url":"https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/img-sign-in.svg","contentUrl":"https:\/\/uhp.digital\/wp-content\/uploads\/2021\/01\/img-sign-in.svg","width":636,"height":484},{"@type":"WebSite","@id":"https:\/\/uhp.digital\/#website","url":"https:\/\/uhp.digital\/","name":"UHP","description":"Delivering digital impact.","publisher":{"@id":"https:\/\/uhp.digital\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/uhp.digital\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/uhp.digital\/#organization","name":"UHP","url":"https:\/\/uhp.digital\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/uhp.digital\/#\/schema\/logo\/image\/","url":"https:\/\/uhp.digital\/wp-content\/uploads\/2020\/01\/uhp-logo.svg","contentUrl":"https:\/\/uhp.digital\/wp-content\/uploads\/2020\/01\/uhp-logo.svg","width":88,"height":40,"caption":"UHP"},"image":{"@id":"https:\/\/uhp.digital\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/uhpdigital\/","https:\/\/www.instagram.com\/uhpdigital\/","https:\/\/www.linkedin.com\/company\/uhp-software\/"]},{"@type":"Person","@id":"https:\/\/uhp.digital\/#\/schema\/person\/82c263f7a03b60653db3cdd2d4301acb","name":"UHP","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/uhp.digital\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/c1bc770aea92efb4d58edb8d8e86f9eaa06def97a45852ce534799e57534d6c6?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c1bc770aea92efb4d58edb8d8e86f9eaa06def97a45852ce534799e57534d6c6?s=96&d=mm&r=g","caption":"UHP"}}]}},"_links":{"self":[{"href":"https:\/\/uhp.digital\/en\/wp-json\/wp\/v2\/posts\/5953","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/uhp.digital\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/uhp.digital\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/uhp.digital\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/uhp.digital\/en\/wp-json\/wp\/v2\/comments?post=5953"}],"version-history":[{"count":11,"href":"https:\/\/uhp.digital\/en\/wp-json\/wp\/v2\/posts\/5953\/revisions"}],"predecessor-version":[{"id":5970,"href":"https:\/\/uhp.digital\/en\/wp-json\/wp\/v2\/posts\/5953\/revisions\/5970"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/uhp.digital\/en\/wp-json\/wp\/v2\/media\/5960"}],"wp:attachment":[{"href":"https:\/\/uhp.digital\/en\/wp-json\/wp\/v2\/media?parent=5953"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/uhp.digital\/en\/wp-json\/wp\/v2\/categories?post=5953"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/uhp.digital\/en\/wp-json\/wp\/v2\/tags?post=5953"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}