{"action":"created","comment":{"url":"https://api.github.com/repos/ga-dc/curriculum/pulls/comments/44364944","id":44364944,"diff_hunk":"@@ -0,0 +1,365 @@\n+# Devise! and sessions\n+\n+## Learning Objectives\n+- explain what state is in a web application\n+- explain how sessions give state to a web application\n+- explain how user authentication utilizes sessions\n+- Define and then access a session variable in a Rails application.\n+- set session hash key value pairs inside of a rails application\n+- implement user authentication into a web application utilizing the devise gem\n+- implement useful helper methods devise provides\n+\n+### Opening Framing (10m)\n+- So we've figured out how to execute CRUD functionality into our apps. This is great, but should anyone using our application be able to do whatever they want? It would really suck if your buddies could post for you on facebook or if someone withdrew money from your banking site.\n+\n+### T & T\n+Well, that shouldn't be the case. We need to be able to perserve a \"state\" of the application. If a user is logged in, that user should be logged in until he logs out, persisting the state of that user being logged in. For the next 5 minutes turn to your partner in class and discuss how we might be able to prevent people from doing whatever they want on your website.\n+\n+Here's some talking points:\n+- What does it mean for a user to be signed in?\n+- For that matter, what does it mean to be a user? How are we encapsulating that data.\n+- We've used our backend to store data about apartments and tenants. Can we use it to store data about a user itself?\n+\n+> We need to start thinking about how to capture information into a User model. That has information about username, email, or password. We also need a way to transfer or perserve state in our applications from request to request.\n+\n+## Cookies\n+\n+### We do:\n+1. In Chrome, go to Preferences\n+- Show advanced settings\n+- Click \"Content settings\"\n+- Click \"All cookies and site data\"\n+- Scroll to `github.com`\n+\n+Click around on the different \"buttons\" or \"tabs\". In particular, look at `dotcom_user`, `signed_in`, and `tz`.\n+\n+##### Turn and talk: What do you see? What do these do?\n+\n+A *cookie* is a piece of data stored on your computer by your web browser and associated with a particular website.\n+\n+### Example cookies:\n+\n+From Github:\n+```\n+Name: dotcom_user\n+Content: RobertAKARobin\n+Domain: .github.com\n+Path: /\n+Send for: Secure connections only\n+Accessible to script: No (HttpOnly)\n+Created: Wednesday, July 22, 2015 at 7:04:22 PM\n+Expires: Sunday, July 22, 2035 at 7:04:22 PM\n+```\n+\n+## Enter Sessions(i do, talk + setup)15m\n+- HTTP is stateless, so it's up to either the browser or application that needs to \"remember\" what's happening\n+- A session is just a place to store data during one request that you can read during later requests.\n+- A session is a hash containing key value pairs that provide state in your application\n+\n+Let's hop into some code so we can see sessions in action.\n+\n+The code we'll be working with today can be found [here](https://github.com/ga-dc/tunr_rails_sessions_devise) This is a version of the tunr rails application we've been building on this week. It contains everything that we've learned up until now.\n+\n+Make sure you fork/clone this repo if you would like to follow along. It is not too important to follow along for this portion of this lesson. I encourage you to just watch and use the following code to practice it yourself later.\n+\n+## Set and Use session key-value pairs\n+\n+In order to understand sessions, we're going to add some code to our existing artists controller. In `app/controllers/artists_controller.rb`:\n+\n+```ruby\n+# this action will set `test: \"this string was set on the testing_session action\"` as a key value pair in the session\n+def testing_session\n+  session[:test] = \"this string was set on the testing_session action\"\n+end\n+\n+# also add @test = session[:test] to index action\n+def index\n+  @test = session[:test]\n+  @artists = Artist.all\n+end\n+```\n+\n+Let's update our `app/views/artists/index.html.erb` to include the use of our new instance variable `@test`. Place the following code somewhere in that file:\n+\n+```html\n+<h1>The value of @test is: <%= @test %></h1>\n+```\n+\n+Now because we created this action, let's update our `config/routes.rb` to listen for a request to that action:\n+\n+```ruby\n+get '/artists/testing_session', to: 'artists#testing_session'\n+```\n+\n+Finally we need to create a view for this action. Lets create that now `$ touch views/artists/testing_session.html.erb`. Let's make this view simple and just put in the following content.\n+\n+```html\n+<h1>A session key value pair is being set</h1>\n+```\n+\n+Let's first navigate to our artists index route at `http://localhost:3000/artists`.\n+\n+We can see that there is nothing after `The value of @test is: `\n+\n+Now let's navigate to `http://localhost:3000/artists/testing_session`\n+\n+Great that's nice, our view was generated, but more importantly we had a key-value pair get set in this request because of the `testing_session` action in our artists controller:\n+\n+```ruby\n+def testing_session\n+  session[:test] = \"this was set on the testing_session action\"\n+end\n+```\n+\n+How do we verify this session key-value pair was set? Let's navigate back to artists index path.\n+\n+Now we can see `The value of @test is: this was set on the testing_session action`\n+\n+If we open a new incognito window and navigate to `http://localhost:3000/artists`, we'll see the session isn't set in that browser because it's a brand new session.\n+\n+When we clear our cookies/session in our browser we can see in our index route that `@test` becomes nil again.\n+\n+> Now that we have the ability to transfer information from request to request. We can preserve state in our application.\n+\n+## Setting objects in sessions\n+Instead of hardcoding strings into our sessions hash, lets see if we can store objects themselves in the session.\n+\n+Let's update our show action to set a session. In `app/controllers/artists_controller.rb`:\n+\n+```ruby\n+def index\n+  @last_viewed_artist = session[:last_viewed_artist]\n+  @artists = Artist.all\n+end\n+\n+def show\n+  @artist = Artist.find(params[:id])\n+  session[:last_viewed_artist] = @artist\n+end\n+```\n+\n+In your `app/views/artists/index.html.erb place the following:\n+\n+```html\n+<h3>Last viewed artist: <%= @artist[\"name\"] %></h3>\n+```\n+\n+Now every time We click on an artists show page it will update the session to contain the most recently viewed artist. Then any time we make a request to the artists index path we can see the most recently viewed artist's name.\n+\n+> So now we can store objects or attributes of objects in our sessions as well. This may include id's of a user model, which is basically what devise is going to do for us when a user \"signs in\"\n+\n+## Deleting parts of the session\n+Lets add a new action/route/view for deleting session.\n+\n+In `app/controllers/artists_controller.rb`:\n+\n+```ruby\n+def deleting_session\n+  session.delete(:last_viewed_artist)\n+end\n+```\n+\n+In `config/routes.rb`:\n+\n+```ruby\n+get '/artists/deleting_session', to: 'artists#deleting_session'\n+```\n+\n+Lets create `app/views/artists/deleting_session.html.erb` and add the following content:\n+\n+```html\n+<h1>deleting the last viewed artist session key value pair</h1>\n+```\n+\n+When we navigate from the `deleting_session` route back to the artist we can see an error of undefined method.\n+\n+> This is the sort of thing thats happening when a user \"logs out\"\n+\n+Checkout the [testing_sessions branch](https://github.com/ga-dc/tunr_rails_sessions_devise/tree/testing_sessions) for all the code thus far.\n+\n+### You do\n+Take the next 5 minutes to:\n+- create a new action in the posts controller that instantiates a session key-value pair\n+- save it to an instance variable in the index, and have it display in the index view\n+","path":"05-mvc-with-rails/rails-sessions-and-auth-with-devise/readme.md","position":184,"original_position":184,"commit_id":"bfc958a6fef4e9363de2caaaec2d6fe519586196","original_commit_id":"bfc958a6fef4e9363de2caaaec2d6fe519586196","user":{"login":"jshawl","id":3824954,"avatar_url":"https://avatars.githubusercontent.com/u/3824954?v=3","gravatar_id":"","url":"https://api.github.com/users/jshawl","html_url":"https://github.com/jshawl","followers_url":"https://api.github.com/users/jshawl/followers","following_url":"https://api.github.com/users/jshawl/following{/other_user}","gists_url":"https://api.github.com/users/jshawl/gists{/gist_id}","starred_url":"https://api.github.com/users/jshawl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jshawl/subscriptions","organizations_url":"https://api.github.com/users/jshawl/orgs","repos_url":"https://api.github.com/users/jshawl/repos","events_url":"https://api.github.com/users/jshawl/events{/privacy}","received_events_url":"https://api.github.com/users/jshawl/received_events","type":"User","site_admin":false},"body":"noticing a lack of industry examples here - maybe you can use the concept of a shopping cart. sessions are great for these temporary data stores","created_at":"2015-11-10T02:49:53Z","updated_at":"2015-11-10T02:49:53Z","html_url":"https://github.com/ga-dc/curriculum/pull/435#discussion_r44364944","pull_request_url":"https://api.github.com/repos/ga-dc/curriculum/pulls/435","_links":{"self":{"href":"https://api.github.com/repos/ga-dc/curriculum/pulls/comments/44364944"},"html":{"href":"https://github.com/ga-dc/curriculum/pull/435#discussion_r44364944"},"pull_request":{"href":"https://api.github.com/repos/ga-dc/curriculum/pulls/435"}}},"pull_request":{"url":"https://api.github.com/repos/ga-dc/curriculum/pulls/435","id":50078540,"html_url":"https://github.com/ga-dc/curriculum/pull/435","diff_url":"https://github.com/ga-dc/curriculum/pull/435.diff","patch_url":"https://github.com/ga-dc/curriculum/pull/435.patch","issue_url":"https://api.github.com/repos/ga-dc/curriculum/issues/435","number":435,"state":"open","locked":false,"title":"adds first draft to devise lesson","user":{"login":"andrewsunglaekim","id":8976305,"avatar_url":"https://avatars.githubusercontent.com/u/8976305?v=3","gravatar_id":"","url":"https://api.github.com/users/andrewsunglaekim","html_url":"https://github.com/andrewsunglaekim","followers_url":"https://api.github.com/users/andrewsunglaekim/followers","following_url":"https://api.github.com/users/andrewsunglaekim/following{/other_user}","gists_url":"https://api.github.com/users/andrewsunglaekim/gists{/gist_id}","starred_url":"https://api.github.com/users/andrewsunglaekim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andrewsunglaekim/subscriptions","organizations_url":"https://api.github.com/users/andrewsunglaekim/orgs","repos_url":"https://api.github.com/users/andrewsunglaekim/repos","events_url":"https://api.github.com/users/andrewsunglaekim/events{/privacy}","received_events_url":"https://api.github.com/users/andrewsunglaekim/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-11-09T02:14:53Z","updated_at":"2015-11-10T02:49:53Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4ca7fc2c335938b7007af8e444c7f8670aabeeb2","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/ga-dc/curriculum/pulls/435/commits","review_comments_url":"https://api.github.com/repos/ga-dc/curriculum/pulls/435/comments","review_comment_url":"https://api.github.com/repos/ga-dc/curriculum/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ga-dc/curriculum/issues/435/comments","statuses_url":"https://api.github.com/repos/ga-dc/curriculum/statuses/bfc958a6fef4e9363de2caaaec2d6fe519586196","head":{"label":"ga-dc:rails_devise","ref":"rails_devise","sha":"bfc958a6fef4e9363de2caaaec2d6fe519586196","user":{"login":"ga-dc","id":10747017,"avatar_url":"https://avatars.githubusercontent.com/u/10747017?v=3","gravatar_id":"","url":"https://api.github.com/users/ga-dc","html_url":"https://github.com/ga-dc","followers_url":"https://api.github.com/users/ga-dc/followers","following_url":"https://api.github.com/users/ga-dc/following{/other_user}","gists_url":"https://api.github.com/users/ga-dc/gists{/gist_id}","starred_url":"https://api.github.com/users/ga-dc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ga-dc/subscriptions","organizations_url":"https://api.github.com/users/ga-dc/orgs","repos_url":"https://api.github.com/users/ga-dc/repos","events_url":"https://api.github.com/users/ga-dc/events{/privacy}","received_events_url":"https://api.github.com/users/ga-dc/received_events","type":"Organization","site_admin":false},"repo":{"id":36871385,"name":"curriculum","full_name":"ga-dc/curriculum","owner":{"login":"ga-dc","id":10747017,"avatar_url":"https://avatars.githubusercontent.com/u/10747017?v=3","gravatar_id":"","url":"https://api.github.com/users/ga-dc","html_url":"https://github.com/ga-dc","followers_url":"https://api.github.com/users/ga-dc/followers","following_url":"https://api.github.com/users/ga-dc/following{/other_user}","gists_url":"https://api.github.com/users/ga-dc/gists{/gist_id}","starred_url":"https://api.github.com/users/ga-dc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ga-dc/subscriptions","organizations_url":"https://api.github.com/users/ga-dc/orgs","repos_url":"https://api.github.com/users/ga-dc/repos","events_url":"https://api.github.com/users/ga-dc/events{/privacy}","received_events_url":"https://api.github.com/users/ga-dc/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ga-dc/curriculum","description":"","fork":false,"url":"https://api.github.com/repos/ga-dc/curriculum","forks_url":"https://api.github.com/repos/ga-dc/curriculum/forks","keys_url":"https://api.github.com/repos/ga-dc/curriculum/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ga-dc/curriculum/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ga-dc/curriculum/teams","hooks_url":"https://api.github.com/repos/ga-dc/curriculum/hooks","issue_events_url":"https://api.github.com/repos/ga-dc/curriculum/issues/events{/number}","events_url":"https://api.github.com/repos/ga-dc/curriculum/events","assignees_url":"https://api.github.com/repos/ga-dc/curriculum/assignees{/user}","branches_url":"https://api.github.com/repos/ga-dc/curriculum/branches{/branch}","tags_url":"https://api.github.com/repos/ga-dc/curriculum/tags","blobs_url":"https://api.github.com/repos/ga-dc/curriculum/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ga-dc/curriculum/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ga-dc/curriculum/git/refs{/sha}","trees_url":"https://api.github.com/repos/ga-dc/curriculum/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ga-dc/curriculum/statuses/{sha}","languages_url":"https://api.github.com/repos/ga-dc/curriculum/languages","stargazers_url":"https://api.github.com/repos/ga-dc/curriculum/stargazers","contributors_url":"https://api.github.com/repos/ga-dc/curriculum/contributors","subscribers_url":"https://api.github.com/repos/ga-dc/curriculum/subscribers","subscription_url":"https://api.github.com/repos/ga-dc/curriculum/subscription","commits_url":"https://api.github.com/repos/ga-dc/curriculum/commits{/sha}","git_commits_url":"https://api.github.com/repos/ga-dc/curriculum/git/commits{/sha}","comments_url":"https://api.github.com/repos/ga-dc/curriculum/comments{/number}","issue_comment_url":"https://api.github.com/repos/ga-dc/curriculum/issues/comments{/number}","contents_url":"https://api.github.com/repos/ga-dc/curriculum/contents/{+path}","compare_url":"https://api.github.com/repos/ga-dc/curriculum/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ga-dc/curriculum/merges","archive_url":"https://api.github.com/repos/ga-dc/curriculum/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ga-dc/curriculum/downloads","issues_url":"https://api.github.com/repos/ga-dc/curriculum/issues{/number}","pulls_url":"https://api.github.com/repos/ga-dc/curriculum/pulls{/number}","milestones_url":"https://api.github.com/repos/ga-dc/curriculum/milestones{/number}","notifications_url":"https://api.github.com/repos/ga-dc/curriculum/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ga-dc/curriculum/labels{/name}","releases_url":"https://api.github.com/repos/ga-dc/curriculum/releases{/id}","created_at":"2015-06-04T13:18:59Z","updated_at":"2015-11-06T14:59:58Z","pushed_at":"2015-11-09T22:49:06Z","git_url":"git://github.com/ga-dc/curriculum.git","ssh_url":"git@github.com:ga-dc/curriculum.git","clone_url":"https://github.com/ga-dc/curriculum.git","svn_url":"https://github.com/ga-dc/curriculum","homepage":"https://ga-dc.github.io/curriculum/","size":130094,"stargazers_count":16,"watchers_count":16,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":117,"mirror_url":null,"open_issues_count":73,"forks":117,"open_issues":73,"watchers":16,"default_branch":"master"}},"base":{"label":"ga-dc:master","ref":"master","sha":"785e120b20f7de8eb2bc240605b4879fbf9eac18","user":{"login":"ga-dc","id":10747017,"avatar_url":"https://avatars.githubusercontent.com/u/10747017?v=3","gravatar_id":"","url":"https://api.github.com/users/ga-dc","html_url":"https://github.com/ga-dc","followers_url":"https://api.github.com/users/ga-dc/followers","following_url":"https://api.github.com/users/ga-dc/following{/other_user}","gists_url":"https://api.github.com/users/ga-dc/gists{/gist_id}","starred_url":"https://api.github.com/users/ga-dc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ga-dc/subscriptions","organizations_url":"https://api.github.com/users/ga-dc/orgs","repos_url":"https://api.github.com/users/ga-dc/repos","events_url":"https://api.github.com/users/ga-dc/events{/privacy}","received_events_url":"https://api.github.com/users/ga-dc/received_events","type":"Organization","site_admin":false},"repo":{"id":36871385,"name":"curriculum","full_name":"ga-dc/curriculum","owner":{"login":"ga-dc","id":10747017,"avatar_url":"https://avatars.githubusercontent.com/u/10747017?v=3","gravatar_id":"","url":"https://api.github.com/users/ga-dc","html_url":"https://github.com/ga-dc","followers_url":"https://api.github.com/users/ga-dc/followers","following_url":"https://api.github.com/users/ga-dc/following{/other_user}","gists_url":"https://api.github.com/users/ga-dc/gists{/gist_id}","starred_url":"https://api.github.com/users/ga-dc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ga-dc/subscriptions","organizations_url":"https://api.github.com/users/ga-dc/orgs","repos_url":"https://api.github.com/users/ga-dc/repos","events_url":"https://api.github.com/users/ga-dc/events{/privacy}","received_events_url":"https://api.github.com/users/ga-dc/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ga-dc/curriculum","description":"","fork":false,"url":"https://api.github.com/repos/ga-dc/curriculum","forks_url":"https://api.github.com/repos/ga-dc/curriculum/forks","keys_url":"https://api.github.com/repos/ga-dc/curriculum/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ga-dc/curriculum/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ga-dc/curriculum/teams","hooks_url":"https://api.github.com/repos/ga-dc/curriculum/hooks","issue_events_url":"https://api.github.com/repos/ga-dc/curriculum/issues/events{/number}","events_url":"https://api.github.com/repos/ga-dc/curriculum/events","assignees_url":"https://api.github.com/repos/ga-dc/curriculum/assignees{/user}","branches_url":"https://api.github.com/repos/ga-dc/curriculum/branches{/branch}","tags_url":"https://api.github.com/repos/ga-dc/curriculum/tags","blobs_url":"https://api.github.com/repos/ga-dc/curriculum/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ga-dc/curriculum/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ga-dc/curriculum/git/refs{/sha}","trees_url":"https://api.github.com/repos/ga-dc/curriculum/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ga-dc/curriculum/statuses/{sha}","languages_url":"https://api.github.com/repos/ga-dc/curriculum/languages","stargazers_url":"https://api.github.com/repos/ga-dc/curriculum/stargazers","contributors_url":"https://api.github.com/repos/ga-dc/curriculum/contributors","subscribers_url":"https://api.github.com/repos/ga-dc/curriculum/subscribers","subscription_url":"https://api.github.com/repos/ga-dc/curriculum/subscription","commits_url":"https://api.github.com/repos/ga-dc/curriculum/commits{/sha}","git_commits_url":"https://api.github.com/repos/ga-dc/curriculum/git/commits{/sha}","comments_url":"https://api.github.com/repos/ga-dc/curriculum/comments{/number}","issue_comment_url":"https://api.github.com/repos/ga-dc/curriculum/issues/comments{/number}","contents_url":"https://api.github.com/repos/ga-dc/curriculum/contents/{+path}","compare_url":"https://api.github.com/repos/ga-dc/curriculum/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ga-dc/curriculum/merges","archive_url":"https://api.github.com/repos/ga-dc/curriculum/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ga-dc/curriculum/downloads","issues_url":"https://api.github.com/repos/ga-dc/curriculum/issues{/number}","pulls_url":"https://api.github.com/repos/ga-dc/curriculum/pulls{/number}","milestones_url":"https://api.github.com/repos/ga-dc/curriculum/milestones{/number}","notifications_url":"https://api.github.com/repos/ga-dc/curriculum/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ga-dc/curriculum/labels{/name}","releases_url":"https://api.github.com/repos/ga-dc/curriculum/releases{/id}","created_at":"2015-06-04T13:18:59Z","updated_at":"2015-11-06T14:59:58Z","pushed_at":"2015-11-09T22:49:06Z","git_url":"git://github.com/ga-dc/curriculum.git","ssh_url":"git@github.com:ga-dc/curriculum.git","clone_url":"https://github.com/ga-dc/curriculum.git","svn_url":"https://github.com/ga-dc/curriculum","homepage":"https://ga-dc.github.io/curriculum/","size":130094,"stargazers_count":16,"watchers_count":16,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":117,"mirror_url":null,"open_issues_count":73,"forks":117,"open_issues":73,"watchers":16,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ga-dc/curriculum/pulls/435"},"html":{"href":"https://github.com/ga-dc/curriculum/pull/435"},"issue":{"href":"https://api.github.com/repos/ga-dc/curriculum/issues/435"},"comments":{"href":"https://api.github.com/repos/ga-dc/curriculum/issues/435/comments"},"review_comments":{"href":"https://api.github.com/repos/ga-dc/curriculum/pulls/435/comments"},"review_comment":{"href":"https://api.github.com/repos/ga-dc/curriculum/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ga-dc/curriculum/pulls/435/commits"},"statuses":{"href":"https://api.github.com/repos/ga-dc/curriculum/statuses/bfc958a6fef4e9363de2caaaec2d6fe519586196"}}}}