Best way to connect a Angular App with ERPNext

Will this change the api_secret if same user logs in from 2 devices?

Actually yes. Only the last logged in device works. In my case, the other devices gets logged out automatically and redirects back to the login page.

thx @hashir that helps a lot

but i still have the usecase where i need to login a User only with an ID (RFID or in my current case his email address)

do you have any advice how I can solve this?

the ‘usr’ parameter in my above example can be username, email address or mobile number (from user doctype) provided that the following are enabled in the system settings

If you want seamless single sign on in your custom app, create OAuth Client and use OAuth 2.
That will make sure multiple devices can login and get separate bearer token for each device.

Still CORS needs to be configured if it is browser only app.

This is Angular/Ionic sample mobile app, it uses OAuth 2 code grant with refresh token.
It is using native http calls from mobile platform to workaround CORS.

you can make it into a PWA to be served from browser if you enable CORS for domain from where app will be served.

1 Like

@revant_one i have my users registering themselves from the app as new users. Can OAuth be applied in this scenario?

As long as user is able to login using standard login page, it’ll work. It will also work if user selects social login option.

1 Like

I was able to run this Ionic mobile App and login and fetching sales invoice was successful.

I changed appUrl: ‘frappe://’ to ‘http://localhost:8100’ so that i can test in browser also
Also i call this.token.processCode(window.location.href) in ngOnInit at home page so that the auth code returned is exchanged for access token

All is good but the problem is when i logout, frappe.integrations.oauth2.revoke_token endpoint is called an it fails with Bad Request error

When this happens repeatedly, fail2ban block my ip for 10 mins.

How to ensure that this doesnt happen or how to make the revoke token call successful?

What’s the response? Check the response tab.

Check this as well, it supports ionic capacitor castlecraft / capacitor-starter · GitLab

Check request, it should be like this frappe/test_oauth20.py at b4d57b0174a16035ffe3024ac04f1f87944a448d · frappe/frappe · GitHub

This is the response

As per the test, it requires headers and token which are being passed as expected from browser

request-header in this image seems to be Content-Type: text/plain

Can you try the same request without any other header and only {"content-type": "application/x-www-form-urlencoded"}

Try it in postman.

I’ll try on my end today.

Can you try the other starter? Just try the basic login and logout, On logout it should revoke token.

The OAuth Bearer Token doctype will show status Revoked

Sure, will try and post the outcome

This works. I receive success response and i checked at the table as well, it sets the status to “Revoked”
Tested using Postman

No sure if i am doing it the right way, but still posting my observation

  • I revoked the token using postman
  • The token is no more valid but still my request is passing through and i get response for get Sales Invoice in the angular App
  • I removed the token from the header of the request by clearing the local storage in Chrome
  • Still the get Sales Invoice was successful
  • Realized that since while approving the Authorization request, i login at the frappe frontend, it sets the cookie. So even after the token becomes invalid, this cookie is used to process the request of get Sales Invoice
  • Even if i logout, it only will clear the local storage i guess, the request will still pass through using the cookie.

That was intended. It is like “Login with Google” for ERPNext. When erpnext user logout, google user is still in session for other services.

Workaround is to redirect user to logout after everything is clear from app.

window.location.href = authServerUrl + '?cmd=web_logout';

Please see this screen recording. I am not sure what is happening.

Once the API call is successful. If i click the same button next time, it wont also, not able to access from frappe frontend.

This is my API call

getData(){
this.http.get<any>(`https://xxx.yyy.com//api/method/frappe.desk.form.load.getdoc`, {
  withCredentials: true,
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'Authorization': 'Bearer ' + this.accessToken
  },
  params: {
    doctype: 'Sales Invoice',
    name: 'SINV-21-00010',
  },
}).subscribe({
  next: data => {
    console.log(data);        
  }
})

}

I just tried this capacitor repo, it revokes the token properly.

But the same issue as shown in the recording is encountered here as well. One time call to the API works, subsequent calls fail. Also not able to open frappe frontend in separate tab. but opens up in incognito window.
Looks like something to do with the cookie.

don’t use withCredentials. It’s for session based apps. We are doing token based access.

Wow! This fixed all the issues. Login, Logout, token revoke and login from Frappe Frontend.

Thanks alot. I blindly copied the getData function from my current angular app which runs on cookie