turbolinks / turbolinks-ios

Native iOS adapter for building hybrid apps with Turbolinks 5
MIT License
881 stars 92 forks source link

Prevent going back in certain situations #100

Closed reinink closed 7 years ago

reinink commented 7 years ago

Hello! I'm just getting started with this library, and I'm wondering if there is anyway to prevent the back navigation in certain situations?

For example, I have a login page, that once logged in, I'd love to have the < Login link removed. This is what it looks like now:

image

Is there an approach built into Turbolinks for this?

thetizzo commented 7 years ago

Hi,

The way I solved this problem was to do what the Demo App is doing for the protected area example.

Basically you need your server to return a 401 status on a failed auth and then the SessionDelegate method session:didFailRequestForVisitable in your ApplicationController can catch that and present an Auth controller that can handle log in and update the WKWebViewConfiguration so the rest of the views know you are logged in.

reinink commented 7 years ago

@thetizzo Hah! I was just reading your blog post on this. :)

I'm pretty new to iOS development. Is the Swift code in your blog post Swift 3, or 2.x? I'm running into quite a few challenges getting this all up and running, because all the examples are Swift 2.x, but the library is now Swift 3.

And yes, this sounds like a great approach! Thanks for your help. 👍

reinink commented 7 years ago

@thetizzo While I'm bugging you for help, how have you found this works out for remembering your user's session? Is it able to remember it for a long period of time? Or does a user have to re-login each time they use the app?

I figured the standard "remember me" functionality might work nice here. I'm assuming the cookie will be remember for a long time on iOS.

thetizzo commented 7 years ago

That is Swift 2.x in that post because I have bad timing 😄

I believe the Demo App has been updated to 3.0 and is a much better reference than the code in my post because you can run it locally and play with it to see how it works.

For remembering the session, I found this pull request to be very helpful.

Basically if you use persistent sessions (save them on the server) then the app will automatically reload the session using the cookie. Then you can control the length with the expiration date in the cookie.

Assuming you are using Rails as a back end, this gem works super well for me: https://github.com/rails/activerecord-session_store

reinink commented 7 years ago

@thetizzo Amazing! I didn't realize that the demo app has been updated to 3.0. I'm going to have a closer look at that.

And I'm actually using Laravel as my backend, but it has the exact same sort of session persistence. That sounds way too easy.

thetizzo commented 7 years ago

I agree. It does sounds way too easy. 😏

reinink commented 7 years ago

@thetizzo So, here's a tricky one. How did you handle logging out? :)

thetizzo commented 7 years ago

Honestly I haven't yet, but I think you could add it in a pretty standard way and as long as your server deletes the cookie out of the DB then it should work.

zachwaugh commented 7 years ago

As far as hiding the back button, it would better to never push a new view controller on the navigation stack to begin with. To do this, you could either do login in a modal, as suggested above and done in the demo app, or when login is successful, do a replace instead of an advance, to use the Turbolinks terminology, so that the login view controller is replaced with the logged-in view controller

For logging out, it depends on your app needs. It should work just the same as logging out of your web app. If you just want to app to "forget" your session (i.e. - not remove from the server), all you need to do is delete the cookies which you can do using the WKWebsiteDataStore class.

reinink commented 7 years ago

Thanks @thetizzo and @zachwaugh.

The issue I had with logging out wasn't the act of logging out as much as trying to clear the session history in Turbolinks. Right now I've got it working where when you log back in, you can click back and go through the previous user's browsing history. That seems weird.

What's the best way to clear the history within Turbolinks iOS?

zachwaugh commented 7 years ago

What we do is create is tear down everything whenever the user logs out or switches accounts. We destroy the existing Turbolinks.Session and create a new one, so there is a new webview and it doesn't have any of the old state.

reinink commented 7 years ago

@zachwaugh Perfect, that makes sense! I'll try do that. :)

RNZ01 commented 5 years ago

@zachwaugh Hey, I have a tab bar based app and I want to implement a logout functionality, How do I create a new method to destroy the existing Turbolinks.Sessions for all tabs? is there any method, function to call? similar to reloadSession(), reloadVisitable() ? Thanks.

zachwaugh commented 5 years ago

@ramyalzayat you shouldn't need to actively destroy the session, just remove all references to it and let it be deallocated, then you can create a new session.