Good day.
I'm trying to implement a login page in SwiftUI, but I'm unable to figure out how to make the application prompt the user to save their credentials after a successful login.
This is the code for the input fields.
TextField("Phone number", text: $phoneNumber)
.keyboardType(.numbersAndPunctuation)
.textContentType(.username)
SecureField("Password", text: $password)
.keyboardType(.asciiCapable)
.textContentType(.password)
On success, an environment variable changes, and the parent component will stop rendering the login page.
I've enabled the "Autofill Credential Provider" entitlement.
What I am trying to achieve is use of the native "password manager" in
iOS, https://developer.apple.com/documentation/security/password_autofill.
When the user would submit their credentials and successfully authenticate, they should be shown a prompt like the one above, asking them if they want to save the password they used to sign in.
The problem with password autofill is not the UIKit/SwiftUI implementation. To get support in your app, the most important things to get right are:
Add "Associated Domains" capability to your app and set "Domains" to webcredentials:example.com (replacing example.com with a domain you actually own and have access to!).
On your website (accessible under the given domain) place a file named apple-app-site-association into your public accessible root directory in a folder .well-known.
You can test access using the command curl https://www.example.com/.well-known/apple-app-site-association. (Yes, HTTPS must be enabled and have a valid certificate!)
The content of the apple-app-site-association must reference your Apple Developer Team ID and the bundle identifier of your app as follows: (Team ID is "A1BC23REUG" and bundle identifier is "com.example.signin-playground")
{
"webcredentials": {
"apps": [
"A1BC23REUG.com.example.signin-playground"
]
}
}
Mark the input fields in SwiftUI using the appropriate textContentType modifier.
I have written a small example in this gist which I successfully tested.
If autofill is not working (e.g. you get only an unspecific password completion dialog), you normally have to check the bundle/team identifier and the in the apple-app-site-association file. If you changed something in the file recently, it's possible that the content is cached either on your device (so you can delete the app and reinstall it again) or it is cached in Apples CDN network (in which case you can activate an alternate mode as documented here
If the "Would you like to save this password" dialog is not appearing, you either didn't correctly setup "Associated Domains" or the iOS heuristic did not detect a relevant change in your screens.
Related
I'm attempting to use Outh authentication for my PHP request to Salesforce but I can't get my ClientID and SecretID for my app.
I normally have an option to View these values but for some reason I'm unable to view them with an administrator login.
I created a new App and was able to get the credentials successfully, so I know it's not the account permissions preventing me from accessing this information.
Does anyone with experience of Salesforce have any experience with an inability to get these details?
Thanks!
Is it a normal app created in this org or managed connected app, coming from installed package? You can't see secrets of managed app.
For normal app they're hidden behind a button. For me clicking it takes me to email challenge (provide OTC or one-time code we've sent to your mailbox). Completing that I can access the page with key and secret I can copy-paste.
Your user might be misconfigured. Try to fish around with browser's source inspector, maybe the button's there but doesn't render?
<input id="appsetup:setupForm:details:oauthSettingsSection:manageConsumerKeySecretSection:manageConsumer" type="submit" name="appsetup:setupForm:details:oauthSettingsSection:manageConsumerKeySecretSection:manageConsumer" value="Manage Consumer Details" class="btn gsbutton">
Is your email valid in this org (maybe it's a fresh sandbox with ".invalid")? Do you use Multi Factor Authentication? Do you think you have "high assurance session" configured when accessing certain areas of setup? Can be in Setup -> Session Settings or in your Profile
thank you for writing back to me regarding the issue.
The issue I encountered was trying to get the API credentials for an existing app but I was able to create a new App which is posting the Leads successfully into the system.
So the answer to my problem was that the original app was misconfigured when it was created and I was able to create a new App to resolve the problem.
For some reason I deleted so called brand entity at my gcloud console. Now I want to create new one using the command in the console:
gcloud alpha iap oauth-brands create --application_title='EmojiRave' --support_email='rebelusgames#gmail.com'
But the console returns me back : INVALID_ARGUMENT: Request contains an invalid argument.
I've used different formats (using brackets and without them)
I've checked whether I have enough permissions to do it (I use owner account, so it's enough permissions)
I'm desperate.
There are two potential reasons for the failure:
1. Incorrect email address. According to the docs: "This [support] email address can either be a user's address or a Google Groups alias. [...] Note: The user issuing the request must be an owner of the specified support email address."
2. Project is not in an organisation. According to this source (see under limitations): If you're [..] outside a Cloud Orginization most likely you'll get an error on step "Creating oauth brand".
Overall, my suggestion is to update the OAuth Consent Screen via GCP Console.
Go to the Google Cloud Platform Console.
From the projects list, select a project or create a new one.
If the APIs & services page isn't already open, click on the Navigation Menu on the upper left and select APIs & services.
On the left, click OAuth Consent Screen.
Click Edit App.
First, it's not possible to delete the OAuth Consent Screen (Brand) once created. This can be seen from #DaImTo's answer, and the lack of delete option in both gcloud command and in the console.
I also tested your command on my Cloud Shell and it works fine as well. I've checked the documentation with regards gcloud alpha iap oauth-brands and it is currently in ALPHA state. It may change without prior notice and it may not be stable or work to all users. If you still want to use the CLI and request to be allow-listed regarding this command, my suggestion is to contact sales, as instructed on the issue tracker you've made.
I am writing an iOS app and have a dilemma. The app will be used to test the BLE protocol of devices coming off our production line. It needs to be very simple, It is a one button app that automatically connects to devices and tests commands in our protocol and gives a pass or fail result. If it passes the device id is sent to our API to be entered in our database.
My problem is I don't want the user to have to login, but I need to send a username and password to the API to log in. This means the username and password has to be included in the app. I am trying to find out the most secure way to do this. I initially thought I would include a plist in the app with the credentials, enter them in keychain, then delete the plist. However I don't believe you can delete a file included in the app bundle (I get a 513 permission error).
I have 2 questions. Is it secure to include credentials in code? Is there a better way to do this?
Thanks!
No.
Use API to retrieve credentials and store to keychain. Simple call to firebase could solve this. Or use your own backend with your custom “security”.
But even obtaining via API don’t give you 100% security. Everything depends. API solution gives you flexibility and ability to support different versions with different credentials.
PROBLEM
I'm on React Native 0.59.9 (latest at the time of this post), and have a login screen in my mobile app that I would like iOS 12's autofill feature to pick up and save the password for a new user. With what I've set up, the app shows the keyboard with the autofill option but never pop's up the 'Save Password' for a new user's credentials.
What the keyboard autofill looks like right now:
https://imgur.com/6gVpGbU
SOME BACKGROUND INFO
In React Native's documentation, they now expose textContentType in the TextInput component. To set it up for iOS 11 autofill, the username textContentType would be set to 'username' and the password textContentType would be set to 'password'.
RN textContentType documentation:
https://facebook.github.io/react-native/docs/textinput#textcontenttype
For iOS 12 autofill, which is supposed to introduce the 'Save Password' feature to mobile app's as well now (previously was websites only) the configuration is different for the password.
The password textContentType would be set to 'newPassword' instead. This isn't working though, in fact it seems to be buggy and breaks the app as it suggests username's for the password field with this set...
Implementation
What I've tried to do to implement iOS 12's autofill feature in React Native:
<TextInput
placeholder={'Enter username'}
autoCapitalize={'none'}
autoCorrect={false}
textContentType={'username'}
/>
<TextInput
placeholder={'Enter password'}
autoCapitalize={'none'}
autoCorrect={false}
secureTextEntry={true}
textContentType={'newPassword'}
/>
In the mobile provision, I've made sure to enable Associated Domains as an entitlement. (Done through Apple Developer website).
In my domain (for example www.mydomain.com), the file apple-app-site-association (with no extension) that has the following has been put into the root directory and is publicly available (https supported).
{
"webcredentials": {
"apps": [
“ZT978FY6AB.com.company.my.app”,
]
}
}
In XCode, I've set up the Associated Domains to point to that domain.
Example:
webcredentials:www.mydomain.com
OUTPUT
The expected output of implementing this is that iOS pops up the 'Save Password' dialog when a new user enter's their credentials.
What the pop up dialog should look like:
https://imgur.com/GH4hfP8
Instead, it never pops up. The user just heads straight into the app upon successful login without the dialog ever appearing for saving the password. This essentially means that none of my users can save their credentials to the password manager of their choice (not even iCloud keychain).
Since this feature does not seem to be testable on a simulator, I've been testing it on an iPhone 7 Plus with iOS 12.3.1 installed and autofill enabled in the settings as can be seen in the below image.
https://imgur.com/nSEmy7V
Any ideas what I'm doing wrong, or if I'm missing a step?
Got it working! The following was what I did to get it working.
Steps
In the app, in code the username and password fields are as below (notice the textContentType)
<TextInput
placeholder={'Enter username'}
autoCapitalize={'none'}
autoCorrect={false}
textContentType={'username'}
/>
<TextInput
placeholder={'Enter password'}
autoCapitalize={'none'}
autoCorrect={false}
secureTextEntry={true}
textContentType={'password'}
/>
Enable Associated Domains as an entitlement in the mobile provision
In XCode, set the Associated Domains to point to the site which will host the apple-app-site-association file.
webcredentials:www.example.com
Do not include the https part of the URL, and do not include the end which would be /apple-app-site-association
Place the apple-app-site-association file in the root directory "/" of your website and make sure it's publicly available. You can check this in any browser by entering your websites full url with the ending like so:
https://www.example.com/apple-app-site-association
You can try this out on the YouTube URL and Amazon URL as well to see their apple-app-site-association files as an example.
Delete your previous builds from the phone and re-install the new builds with these changes and Apple should make the connection almost immediately. Your first successful new login with fresh credentials should then be prompted with the iOS 'Save Password' pop up. You're done!
Now my users can login with autofill, and the best part is that iOS offers to autofill using touch ID, face ID or passcode depending on the user's phone's setup. So they can login using touch ID or even face ID with no extra work needed in the RN app to get this working. Better yet, if they save it to iCloud, they can move to another device and still be able to login to the app with the same credentials if they want to.
The mistakes I made:
I made a few mistakes, hopefully you can avoid these by reading the following.
The website that hosts the apple-app-site-association has to adhere to Apple's guidelines fully. I made the mistake of initially using a temporary site hosted on AWS. This AWS URL provided both a http and https. Apple did not like this. When I switched over to a website that only hosted https it worked fine. This is critical for the 'Save Password' to work, otherwise Apple doesn't have a key to save your credentials to (it uses your website domain as the key to save the credentials to in the Apple keychain).
The apple-app-site-association syntax matters. If even one of the special symbols is off, it won't work. In my original file above take a close look at the double quotes encapsulating the app id:
{
"webcredentials": {
"apps": [
“ZT978FY6AB.com.company.my.app”,
]
}
}
They aren't the standard double quotes and this was resulting in a file that couldn't be parsed by Apple. When in doubt, copy the one that Apple provides in their documentation page and then modify it's contents as necessary. Changing it to the normal double quotes like below fixed that:
{
"webcredentials": {
"apps": [
"ZT978FY6AB.com.company.my.app",
]
}
}
In the RN side of things all you need is the textContentType={'username'} and textContentType={'password'}. My mistake was thinking that 'newPassword' was needed to prompt the 'Save Password' dialog. Nope. 'newPassword' is used by autofill to suggest strong passwords to new users. In essence, only use 'newPassword' on forms where the user is doing a sign up. Not for login forms.
Something to clarify, this solution works for apps that are just apps. No website with a login required, no bringing over credentials from a website into the app needed, and no webview login setups necessary. This was not apparent when I was going through documentation about autofill. The website that hosts the apple-app-site-association does not need to have any login or anything of the kind, it can just be a plain website with a bit of information (possibly about the app or the company that makes the app).
I'm trying to integrate Paypal login within my Rails app and I can't make it work.
I was following the guide: http://cristianobetta.com/blog/2013/09/27/integrating-login-with-paypal-into-rails/
I created an application from the paypal developer site, and set the followings:
App return URL (test): http:/ /localhost:3000/auth/paypal/callback
App return URL (live): http:/ /localhost:3000/auth/paypal/callback
and I get the error:
"Relying Party Validation error: redirect_uri provided in the request does not match with the registered redirect_uri. Please check the request."
when I try to visit the URL:
http:/ /localhost:3000/auth/paypal
Interesting enough, I get the same error if I input my application credential in the official Paypal API integration tool:
https://devtools-paypal.com/guide/openid/ruby?interactive=ON&env=sandbox
Any ideas?
Thanks
This has changed a bit since the accepted answer, and will presumably change again soon... but here's how you do this now.
Log into developer.paypal.com
Click on Dashboard (https://developer.paypal.com/developer/applications)
Click your app name under "Rest API Apps"
Scroll to the box at the bottom of the screen labeled "Sandbox (or Live) App Settings
Set the Return URL (Where users will be redirected after test transactions)
Click save
NOTE
This Return URL must exactly match the redirect_uri that you pass in via querystring (so it's confusing as to why you'd need to pass it in in the first place)
GOTCHA
At this point in time, the Return URL can seemingly never be updated. In my recent experience, if you don't type it correctly the first time you save it, you will have to create a new app.
You need to set this value inside of your sandbox application on the developer website.
Log into developer.paypal.com
Click Applications
Under My Rest Apps click your App name
Click Edit next to App redirect URLs
Set the return URLs for live or test
Save
I resolved it by setting both the live and test redirect URLs to the same thing.
Plus, I ensured that I ticked to get Personal Information from the advanced settings panel, also adding URLs for privacy and agreement links.
The portal hung when set to localhost addresses for those links, so possibly PayPal tried to dereference them, so I put in real fake URLs.
I was encountering this issue myself, albeit in a Sinatra rather than Rails app - like you, I was using http://localhost:4567/auth/paypal/callback as the return URL - changing it to http://127.0.0.1:4567/auth/paypal/callback on the PayPal dev portal and accessing my app from 127.0.0.1 rather than localhost fixed it for me.