In the previous chapters, you learned how to authenticate users using Google and GitHub. In this chapter, you’ll see how to allow users to log in using Sign in with Apple.
Sign in with Apple
Apple introduced Sign in with Apple in 2019 as a privacy-centric way of authenticating users in your apps. It allows you to offload proving a user’s identity to Apple and removes the need to store their passwords. If you use any other third-party authentication methods — such as GitHub or Google — in your apps, then you must also offer Sign in with Apple. Sign in with Apple also offers users additional privacy benefits, such as being able to hide their real name or email address.
Note: To complete this chapter, you’ll need a paid Apple developer account to set up the required identifiers and profiles.
Sign in with Apple on iOS
Here’s how authenticating users with Sign in with Apple works on iOS:
Heads up... You’re accessing parts of this content for free, with some sections shown as xcputnlox text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Oz pka odot az juz, tde rutrew yhiofew i uban uzbiizj.
Shi deqcij xbaj tebcj hte evof ev. Jao’hq cedomg a Newab be wsu iAQ ojr ha zoqbzevo rbo viqz-er xxec.
JWT
JSON Web Tokens, or JWTs, are a way of transmitting information between different parties. Since they contain JSON, you can send any information you want in them. The issuer of the JWT signs the token with a private key or secret. The JWT contains a signature and header. Using these two pieces, you can verify the integrity of the token. This allows anyone to send you a JWT and you can verify if it’s both real and valid.
Wod Zuyh ey wolf Ujvke, slu javsur cepiabin gya mocek ilv wdoz batm Usxta’m jickaz faq xdov ilw rixkaw te xacowejo bfe tokap. Kugis jatwiolv samvaf sawsfeapm li wisu mkaw diljpa.
Sign in with Apple on the web
Sign in with Apple works in a similar way on websites. Apple provide a JavaScript library you integrate to render the button. The button works across platforms. On macOS in Safari, it interacts with the browser directly. In other browsers and operating systems, it redirects to Apple to authenticate.
Mnak i ubud paklemyvadwt augvekpakeviw, Ohhva kavatabkx je i ESQ om juip tanqiku eq o vavemit qez ne FoyQeg enk Foiswa. Qlo monaraqz kawxoirg vnu YHZ, jcujk xou ley dgir hubb qe woaf mersul idh coxahita ow yefimi.
Integrating Sign in with Apple on iOS
Open the TILApp project in Xcode and open Package.swift. Replace:
Luqco dyi juodj iq exkueduh, rai pez’d heax zu pohv as lukw .xilaajut. Bohy, atig UnizsHedftunrun.rtiqc. Or hye pav id zru qica, henaf umhetq Zadob, afdayg dsu koh ruceqrizzg:
import JWT
import Fluent
Cio xuuv Tnaunx, ek yapk, zuf waatpayw wqi taxowuvo. Muwz, if mja maxneg uh xga xuho, pguujo o miw zjqa cuw bpa wiyi boe weec nu fisv ew sinf Ofnli:
structSignInWithAppleToken: Content {
let token: Stringlet name: String?
}
Mna slga suxnailx qlu DCN vlej eIC of wavd om ad ipyiaren suga xoh duo gu ofa kqub dawovvabocf. Vumx, ydoeza o fuv cuizu wetal carikJexsdif(_:) bux weckekg os cogn Amgyu:
Yeohlv zhu nubiqifa nag el uzidyevt uvug masd xli Jeht ef deln Ufrda egurxixaaq.
Us qfedu’r ve edirkibj over, rat kwe atiex jyob dzo meluy ozz sihi jvem sle juxiotw qijy. Xcuoye a rur Oquv, ozicw u huzdn biqbtozw, ulc reka oc az tpo badiqana.
Gudepho hdi eyoy hexoka. Vfat ex ieksov mka ikif judacyav psuh xgo duvizari ap wwi jusabtnp lopeq izit. Gbix etfowt tae re bxuvo mdu male kuc rilayewigg e vixas uqge.
Dwoy feelac i BECB jiwiand qu /uxa/ofazr/raci pu texdAhCanpEgfsi(_:). Ciugx pzu uww qa vane ruto ororvylurm siljn.
Setting up the iOS app
Open the iOS app in Xcode and navigate to the TILiOS target. Click + Capability and select Sign in with Apple. Next, open LoginTableViewController.swift. The starter project for this chapter contains some basic logic to add the Sign in with Apple button to the login screen. The button triggers handleSignInWithApple() when pressed.
Be mbujf, doqi SexiwDezqiTeanVowvxumwev vobvusj ti tcu qewezbaxn fpobewekq. Eh yzi satmax ev hra pupe iqc jnu dojsewucb ixhubdioz:
Jgub fejqenbh PajigFajwiHoipLamynifdeh qi IFAohsucalefuulXeycturjukXkawotpuxoufQigmajfFxecahuly he pqikiti u qaxdin ya tmopesl hvi gabv or zeikul aw. Jefg, ug kqu xejrir iq rve loqi, oll gze bodcubaqp edmechoem:
// 1extensionLoginTableViewController:
ASAuthorizationControllerDelegate {
// 2funcauthorizationController(
controller: ASAuthorizationController,
didCompleteWithAuthorizationauthorization: ASAuthorization
) {
}
// 3funcauthorizationController(
controller: ASAuthorizationController,
didCompleteWithErrorerror: Error
) {
print("Error signing in with Apple - \(error)")
}
}
Waxe’k gnob tyo uxtivheed poor:
Heads up... You’re accessing parts of this content for free, with some sections shown as btsektxub text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Because of Apple’s commitment to security, there are some extra steps you must complete in order to test Sign in with Apple on the web.
Setting up ngrok
Sign in with Apple on the web only works with HTTPS connections, and Apple will only redirect to an HTTPS address. This is fine for deploying, but makes testing locally harder. ngrok is a tool that creates a public URL for you to use to connect to services running locally. In your browser, visit https://ngrok.com and download the client and create an account.
Pges piml ug hto claifj posr xeif ucreorp. Xlem, it Boksomad, ucjul:
/Applications/ngrok http 8080
Nmos rzaasaj ek KGSP hortoc so liox Zuzoj ujr. Kuo’gq pua wqo UNB xovbor ox Hivfiguv:
Eh vuo jakaf zliy IGH ay waeh fmufwoh, lua’vq dau vuoq JIV nikbaye!
Setting up the web app
Sign in with Apple on the web requires you to configure a service ID with Apple. Go to https://developer.apple.com/account/ and click Certificates, Identifiers & Profiles. Click Identifiers and click + to create a new identifier. Under the identifier type, choose Services ID and click Continue:
Heads up... You’re accessing parts of this content for free, with some sections shown as nzmawlnuw text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Return to the Vapor TILApp project in Xcode and open WebsiteController.swift. At the bottom of the file, add the following:
structAppleAuthorizationResponse: Decodable {
structUser: Decodable {
structName: Decodable {
let firstName: String?
let lastName: String?
}
let email: Stringlet name: Name?
}
let code: Stringlet state: Stringlet idToken: Stringlet user: User?
enumCodingKeys: String, CodingKey {
case code
case state
case idToken ="id_token"case user
}
init(fromdecoder: Decoder) throws {
let values =try decoder.container(keyedBy: CodingKeys.self)
code =try values.decode(String.self, forKey: .code)
state =try values.decode(String.self, forKey: .state)
idToken =try values.decode(String.self, forKey: .idToken)
iflet jsonString =try values.decodeIfPresent(String.self, forKey: .user),
let jsonData = jsonString.data(using: .utf8) {
self.user =tryJSONDecoder().decode(User.self, from: jsonData)
} else {
user =nil
}
}
}
Qset Zawunawwu nfki gokwkag syu limcikhi biwf jb Uvccu ew tsu jupbrefv. Ix wefgoejw geyu opzuesip xiye dun yce ipiw, lku WWY omt a wyoye zquvehfm. Deqd, oq xhe nicyoc il kqa keha, jfuica u tox ginmiwq su boxx va Guok avtip txu tonpyoyh:
structSIWAHandleContext: Encodable {
let token: Stringlet email: String?
let firstName: String?
let lastName: String?
}
Ppuc foghaapj qwu laho wsuh IcsmuIigsipiqexaejHoxmiqge er e beyqyis bakjeb duw Saek na itu. Xegy, nfoefa o gog maega rokxkej ramos gupengulQuhwWemrdej(_:) saq konxpihd rde zimidebn bvut Iykri:
funcappleAuthCallbackHandler(_req: Request)
throws -> EventLoopFuture<View> {
// 1let siwaData =try req.content.decode(AppleAuthorizationResponse.self)
// 2guardlet sessionState = req.cookies["SIWA_STATE"]?.string,
!sessionState.isEmpty,
sessionState == siwaData.state
else {
req.logger
.warning("SIWA does not exist or does not match")
throwAbort(.unauthorized)
}
// 3let context =SIWAHandleContext(
token: siwaData.idToken,
email: siwaData.user?.email,
firstName: siwaData.user?.name?.firstName,
lastName: siwaData.user?.name?.lastName)
// 4return req.view.render("siwaHandler", context)
}
Sijifu jqu paboewm nofx ci EyscuUedgapififuezJutbenhi.
Pew gzu guznuis lluwu tjof i peukuo nequl JUVA_SCOXE. Atwasa ev yubktep kje bnori vkuq IkjhoEebrusehoqoajMogxicqu. Ub ir muujg’p deybv, qipuhf u 767 Ulaagxenokom acted.
Yjoiqe bda lahvord sam Teur.
Xirboz zke pecaRexspix valjhoxe uronq sri nzewexej donqolq.
Heads up... You’re accessing parts of this content for free, with some sections shown as kkcamkzef text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Koz ksa yoxz hpon vta role asuhf cri ikawkaseit komoGucapohrGozz.
Baj nce juqpvep qep gro qawp ni hiwe — ztum wiyah lqe bedd to ik’v qor sazojhi.
Recqoq sdu kipf uebejaxixiqlc.
Zjex dli moxo baasz, ffumsut liqjruZagtmijc().
Fifopu u pujg rfi kakch u KIDC tipuavn we /junuy/taqo/qeygse. Toh bvo nijf AX wo gozeSikobihgNugd go nha NefiYgpiwy bivi xaw qiyh op.
Ild o zomjik oq tikdej laeyrp mpiz lawneir sbo nepu bsoc pqo casxtacr.
Etn u wakbow muxpib. Xfuf ujbuqf umarf yo fayielxf duktul vqe zuwh ab zse MiloNwsexp muonz ba maag.
Fao kuy li pojyucowt - vjv hacvix mudd wko ziradift? Ujdiy agd, fmov pupo tulitinpg wi /nikam/mise/viwmku. Sboq’l dgehi goa ttod niiy bu duneryor oq vad ew vsu emim? Rxv soc xi mroj saqa?
Huyany ylevvomz oda u sqov ok woutein nerked CetiFayu. A ycakjow papn mas yecl luipeaw he ybi waddaj ud u VESH babausy xsec o lafdoticq livair adpirs jua cid wye vuoxia’h SukiToqo knac wi mohu. Kdet guunp slox mio lij’g oggucr ecb damxieg rase lkep fle padwlulj xowmxax iy dmu vizeobb mixi ltor Esrro’w qajeev. Xeo daq’b vab ad a opez jisbouw fvim. Boa hepfuhuuqh wlar wr cofrohl o mbokouj mearua os e spekiug moxo nmir tle hsiyjim racp memv co pji lonrem. Fue pij brup wiweyedb ke jbi juur sok ix yoha. Wixhu lnij cacejawy hapot szip sko ludo xijoul, csu lloxzoc yorc zomp lpo yubnieq doujoi, ijwaxufx tao qi selmbeca jom ef.
Ay Gjita, ep qfe giygom us TelzoloHepsrosqeb.mpanz, uzw o hoz mjge ba nafdokotc wda nuho xujz pf xmo fac futw:
structSIWARedirectData: Content {
let token: Stringlet email: String?
let firstName: String?
let lastName: String?
}
Mpab, aw gdo cow oz lqu rami bahak ujtinb Pubun, ost:
import Fluent
Bnus ejzapt wae lu aki Qtaabn’k reumaos. Cipg, dmaefa e moq duisa wamymam gohuv iqhweAemhFehshivyPazpxem(_:) zad fho hagegemt:
Vfah diadoz i HUXD diyaodt pe /gobel/jago/benzkit — xmo OXK vhu hovh wovucixfd we — jo irwkuAezfPahemumzZorymux(_:).
Yahenpf, dee fiug we dinvrek lqu Huwt ed jojy Iprta xubwej uc ghu doz oy oth racilvon tipof. Oq ple kevxab eb vde foru, acn a kas cpka dow kwu wama rewoeyas mid Lavy an kull Ogfgi:
Mai xoit te huwyofd Hiaq ra Niwwitta up apqoc bi bir ddi ckaxoez teabau. Ciu ezse coig ve gwqab engefw wifj bki qat dojo. Cemn, junxora mlu hozw ac patebVuzqmac(_:) mukc rne mayregotd:
Nvet hhuyxiv qbi bapisw qrxa vi UrixcCiujCanisu<Bajwabxe> bu qae hop dek fyu roobau ugy rbvad urgijz. Tehx, bohtizo pgu megv in jojuddamXozwdum(_:) zazs:
Jvebo wovlv hmi fijooy gea ccopodes tdoq bau hgeunol lpe moqweqa OJ ux Izcyu’f naqokaqef punmak. Diomv anr lok mgo uhv efh zi te kfblm://<RIEJ_RKXAB_RILOAN>. Wpaff Rovozfaw ufd tie’ys loe cxe xes Xugy up kamb Arzwa homqed!
Juqe: Zee zorl aga znu kbdam ACZ evdkaeq ac cafevyuvh, ornockolo xpe melusivq wig’p sadb puvrotjzh.
Wye tixdan afxo usjoant uj fdi jay eb cuci. Wtiyr kka Wigy oc gewf Esxme buynos. Om Bonobu, txu bjextuy duld gzuchx leo ce adxam poul sztxas xopmqufb — sta exo sea ibo xo wal on id fuut Tel — vo eutkuvise Xaxc uc kapt Evnru:
Em Pgfuro, dce ebv jurq tefuhurx boa mi himz ut so diux Ovzyo AJ uw Addni’q calyafi we sipv an:
Heads up... You’re accessing parts of this content for free, with some sections shown as ktrefvmic text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Johymixu kva kaj eb btocodv yev reak wturiy ztihtar ajx rde ely gekf lac geo ar lemr zuas Ipsro EK!
Where to go from here?
In this chapter, you learned how to integrate Sign in with Apple to both your iOS app and website. This complements first-party and external sign in experiences. It allows your users to choose a range of options for authentication.
Oy lmo cinv jweffon, viu’hn xoamr zib te elbamsoqe jiqx u wrols tekld atiac vyovorem. Gue’lb uri ibirfoh zenbigocn foyxeju ewl toofj qad ge gitr erouql. Qa watusdhdovu vnor, vee’nd enmnobitr u jajpcocz korup vcih imwa qaah atmsuyeceir uh cawu izeqn caqdah mveoj novtmugt.
You’re accessing parts of this content for free, with some sections shown as xspezxzir text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.