treehouse : what would you like to learn today?
Web Design Web Development iOS Development

Login with Twitter (Kirby)

  • Issue:

    I'm having trouble trying to figure out how Bastian (Kirby Author) is creating the "Login with Twitter" functionality and integrating it into Kirby. What I'm trying to do is create a blog and use that for my comment section.

    What I know:

    I know that he is using Opauth but not sure if he's integrating that with his current auth plugin. From the looks of his URL's when logging in and out, I believe he is.

    Additionally, someone suggested to use Disqus. The problem with that is that I wouldn't be able to control the UI of the comment form and it's really not what I prefer.

    If you'd like to test this and have a Twitter account, you can go to the forum. I'd love any insight or help trying to solve this.

  • Couldn't his URLs just be redirects?

    Have a look at this:

    https://dev.twitter.com/docs/auth/implementing-sign-twitter

    You'd probably need to develop your own plugin for this, but it doesn't look too challenging. Twitter links to some libraries that might be useful:

    https://dev.twitter.com/docs/twitter-libraries#php

  • @BenWalker Possibly.

    /auth/do:lougout - Not sure how he's doing this.

    I'll take a look at those links you provided. Thanks for the insight.

  • do:logout is an internal thing; he's just "forgetting" your login, it has nothing to do with twitter.

  • @traq I just read up on a way to go about that somewhat except the code was something like if $do = "logout"

  • yeah, it's the same idea. He's just parsing the URL instead of using a query string.

    You can see what he's doing in ./kirby/lib/uri.php.
    You can access those params like
    $someParam = $site->uri()->param( $key );

    So, in this case, you'd do:

      if( $site->uri()->param( 'do' ) == 'logout' ){
          /*  logout  */
      }
    

    The query string approach (?do=logout) will still work, of course.

  • After doing some research, I think I'm making this more complicated than it actually is.

    Process:

    User clicks login

    User gets redirected or popup (preferable) to allow access to their information.

    Twitter API grabs their information

    Somehow I store those credentials (username, possibly email and profile image) so the user doesn't have to accept access every time...or something like that.

    Then, just use php to echo out those credentials (minus email).

    @traq Thanks for clearing that up. Makes better sense than what I was imagining.

  • before you redirect the user, you need to POST to twitter to get an oauth request token.

    Somehow I store those credentials (username, possibly email and profile image) so the user doesn't have to accept access every time...or something like that.

    Twitter returns a userID and a screen name. You'd typically store them in the session.

    You might be interested in Andy Smith's OAuth class. I've never done this myself, but this seems to be a good tutorial.

  • @traq What if the user clears their browser's data (cookies, etc), wouldn't they have to go through the whole process over again?

  • yes; but that's true of any* website login.

    *meaning, of course, "any cookie-based website login."
    In practice, this covers just about all of them, Twitter included.

    In fact, if the user intentionally clears their browser's data, I think it's safe to assume that they want you to forget they were logged in.

  • I started working with Opauth but I'm not sure how to set the DocumentRoot.

    See here: http://cloud.chrisburton.me/M7qv

    I'm also getting this error: http://cloud.chrisburton.me/M7xB

    Line 125 can be found here: http://codepad.org/czuCGZvU

  • I started working with Opauth but I'm not sure how to set the DocumentRoot.

    I think it's just telling you that the example needs to be in your doc root (i.e., that's just how the demo is set up to run; so it needs to be in your website's root). Not "for sure" though, I've never used OAuth.

    I'm also getting this error: http://cloud.chrisburton.me/M7xB

    How are you arriving at that error? "Strategy" refers to "which service you want to use for authentication," such as Twitter or FB. Your problem might be as simple as trying to sign in at /auth instead of /auth/twitter (or FB, etc., whichever)...?

  • @traq

    I think it's just telling you that the example needs to be in your doc root (i.e., that's just how the demo is set up to run; so it needs to be in your website's root). Not "for sure" though, I've never used OAuth.

    But the problem is that I have other files there that may conflict. This is what is confusing to me.

    How are you arriving at that error? "Strategy" refers to "which service you want to use for authentication," such as Twitter or FB. Your problem might be as simple as trying to sign in at /auth instead of /auth/twitter (or FB, etc., whichever)...?

    I downloaded the whole thing from http://opauth.org. It seems that what I downloaded from the site is a bit different than this: https://github.com/uzyn/opauth. I'll download what's on github and try again.

  • @chrisburton

    But the problem is that I have other files there that may conflict. This is what is confusing to me.

    Yeah, I think the demo is meant to be run in isolation - just for you to get familiar with using it. I don't think it's meant to be used "out of the box" on a live site.

    do you have a local server set up where you can try it out? Otherwise, you'd probably have to go through the files and change all of the URLs to match wherever you upload it. That might not be a bad idea, since you'll have to do this anyway to use it on your site.

    I'll look at the script and lend you any insights. : )

  • @traq Hmm. I tried putting my Kirby site into a folder so nothing conflicted and it still doesn't work. So weird. Appreciate the help very much. Thank you.

  • observation:

    you can put OAuth in some other directory, but you have to change the config:

    opauth.conf.php.default

      'path' => '/wherever/you/want/to/put/OAuth',
    

    questions:

    have you downloaded the Twitter strategy?

    do you have a twitter key and secret (you'll need to add these to your config)?
    twitter provides a "non" secret to test with as well: L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg

  • @traq I have. Mind if I message you a zip of what I have?

  • @chrisburton

    not at all. I'm probably going to bed soon, but I'll have a look mañana.

  • @traq Not a problem. Thanks again.

  • I just realized I've been saying "OAuth" this whole time, while we're actually talking about Opauth.

    * * Smacks forehead * *

    goodnight.

  • Ha. I knew what you were referring to regardless. I'm exhausted from trying to figure this out off and on for 10 hours. Have a good one.

  • okay: I got this response

    Authentication error: Opauth returns error auth response. Array ( [error] => Array ( [code] => 401 [raw] => Failed to validate oauth signature and token [provider] => Twitter ) [timestamp] => 2013-01-13T03:53:59+00:00 )

    AFAICT, this is a standard response when the provider (twitter) rejects the authentication attempt.

    So, the Opauth example seems to be working fine, it's just not successful. I don't have my own twitter key+secret to test with - are you sure those you sent me are correct?

  • @traq I'm 99.9% positive. Should I create a completely new set?

  • @traq I created an entirely new application and I'm still getting the same error. I'll send you the new file here in a second.

  • ... Have you set up a callback URL with twitter (it doesn't need to be a real URL, just needs to have a value)?

    ... Have you made your Twitter app an "@Anywhere" app (whatever that means)?

    I'm moving testing onto a live site, just in case it's "localhost" that's the problem - twitter seems to be a stickler about which domains it will authorize requests from. Maybe that's why the example recommends trying FB first.

    I'll let you know.


    edit no, no need to create a new key+secret. I'm getting the same response with my own set.

  • @traq

    ... Have you set up a callback URL with twitter (it doesn't need to be a real URL, just needs to have a value)?

    ... Have you made your Twitter app an "@Anywhere" app (whatever that means)?

    Yes, I have done both.

    I'm moving testing onto a live site, just in case it's "localhost" that's the problem - twitter seems to be a stickler about which domains it will authorize requests from. Maybe that's why the example recommends trying FB first.

    I've tried doing the same thing with no luck. However, once you're redirected to the callback.php file with that error, refresh and it tells you specifically what the issue is.

    no, no need to create a new key+secret. I'm getting the same response with my own set.

    Too late, sorry!

  • @traq Also, I tried this tutorial not too long ago and it worked like a charm. Not sure if I should still go about using it, though.

    http://shiflett.org/blog/2010/sep/twitter-oauth

  • why not? if you got it to work, and it's what you want, go for it.


    did you get an error message besides "Failed to validate oauth signature and token"?

  • also, if you're not testing in your site root, you might have to update the path in the RewriteRule in .htaccess as well as in the conf file.

  • @traq

    did you get an error message besides "Failed to validate oauth signature and token"?

    Well, depends on what URL I went to. If I went to /example, I'd get a PHP error. I went to /example/twitter, I'd get the same error you received and if I refreshed that same page, the error would show what the problem was.

    also, if you're not testing in your site root, you might have to update the path in the RewriteRule in .htaccess as well as in the conf file

    I was testing in the root

  • If I went to /example, I'd get a PHP error. I went to /example/twitter, I'd get the same error you received and if I refreshed that same page, the error would show what the problem was.

    Warning: array_key_exists() ...
    Invalid auth response: Missing key auth response components. ?

    That's actually a PHP error, because when you refreshed the page there was no longer an auth response. The example files have no error checking whatsoever.

    If you got something else, what did it say?

  • @traq

    Warning: array_key_exists() ... Invalid auth response: Missing key auth response components. ?

    That's the one. I didn't receive any other error besides that.

  • From briefly talking to the author of Opauth, this is on Twitter's end apparently.

    Additionally, I read on the discussion area of the API docs that it could be caused by the time of my server not being synced to Twitter's server time. However, I don't see this to be the cause after testing locally and on a live server.

  • From briefly talking to the author of Opauth, this is on Twitter's end apparently.

    Did he have any insights as to what twitter's problem is? AFAICT, Opauth seems to follow twitter's API requirements.

  • @traq No. He just told me to contact Twitter. I just replied to that and basically said, "if it was on Twitter's end, why would it work on an alternate library?".

  • 'cause the alt lib knows what twitter's on about. : )

    is Shiflett's code what you tried that works?

  • @traq Ha. Yes, it is. I got the library from here.

    Now I just have to figure out how to use the API to post comments. Not sure if I should integrate it with Kirby's auth plugin or if that isn't necessary.

  • Is this session-only (twitter provides all info you need, users comment thru twitter), or are you integrating more tightly with your site (twitter authenticates, but you're storing the comments yourself (and possibly other user data also))? Do you need to assign permissions to users that you won't be able to determine indirectly, based on the info twitter provides?

    Basically, are you flat-out using twitter accounts on your site, or are you only using twitter as a sign-in mechanism?

  • @traq Let me turn this around, what would you suggest?

    I just want the user to be able to use their Twitter credentials (username and profile photo) for posting comments. Example.

    In the form, I would also prefer that I have an edit option for the user to correct any mistakes. This stops them from commenting multiple times to clear up an error.

  • Personally, I'd want to keep the comments myself - that doesn't mean it's a "better" solution, it's just what I'd want. I'd maintain my own user/auth system; I'd just have twitter take care of the "sign-in" part. I wouldn't necessarily be using much from the twitter API beyond that, though it would obviously be available.

  • @traq I think it may be smarter to do that in case I switch to something else. I will already have the comments in a database. Any ideas on how to go about this?

    I'd obviously just have a login link that just authenticates (not authorizes) the user. I believe all I need is a single textarea field and some way to allow the user to edit their post. The form will be hidden by default until the user is authenticated. Or would I need some way of verifying the user?

  • Update: The author of Opauth is testing my code

  • @chrisburton

    Are you asking about the login or the comment form or the database?

    Or all three

    (1) Don't include the comment form at all if not logged in.

    (2) Every time you provide a form that's tied to a specific user/action, it should have a token attached to it so you can validate that you gave the form to the particular user (recently).

    (3) I'd think the DB would need to store...

    ... user.id of the comment author
    ... date+time comment was authored
    ... display status (show,hide,starred,buried,etc.)
    ... comment thread id
    ... the comment itself

    You'd need an extra field if you allowed users to comment on comments - the above would work for a simple list (ordered chronologically), but you'd need more if you wanted a tree structure.

    If you wanted to "version" comments (keep a record of edits), you'd need a field to track versions as well.

  • I solved the Opauth issue myself. I only had to add my consumer key and secret into the config file and not into any other files like I was doing.

  • @traq Hmm. Sounds complicated.

    ... user.id of the comment author

    This is to verify and target the user, correct?

    ... date+time comment was authored

    This could be used for displaying comments in a timely order.

    ... display status (show,hide,starred,buried,etc.)

    Not quite sure what I would do with this. Perhaps be able to delete comments?

    ... comment thread id

    This sounds like it's for displaying the information on the correct blog post.

    You'd need an extra field if you allowed users to comment on comments - the above would work for a simple list (ordered chronologically), but you'd need more if you wanted a tree structure.

    I will not be allowing this. If the user wants to reply to another user, @username that user.

    If you wanted to "version" comments (keep a record of edits), you'd need a field to track versions as well.

    Not sure I'm understanding why I would need a separate field just for edits?

  • ... display status (show,hide,starred,buried,etc.)

    Not quite sure what I would do with this. Perhaps be able to delete comments?

    yeah, or for moderation (hide without deleting), or for featuring/downvoting comments.

    If you wanted to "version" comments ...

    Not sure I'm understanding why I would need a separate field just for edits?

    Not exactly what I meant: just a "version number."

    For example, user X leaves a comment, then later edits it. The "edited" comment would actually be an entirely new record in the DB, with the same id (I was thinking a good Primary Key would be userID+publishTime), but a different version number. That way, you'd preserve the original comment in case you ever needed it, and it would still be easy to retrieve only the latest version:

    SELECTfields
    FROM comment
    WHERE userID=userID
    AND publishTime=timestamp
    ORDER BY version DESC
    GROUP BY publishTime

  • @traq Thanks for the explanation and your help. I'll have to do a bit of research on how to write this all up and retrieve content from the DB.

  • Can't wait for you to get this all set up. Clearly the blog post of your life ;)

  • @TheDoc Haha. Thanks, Gray. It's definitely going to be my first post for sure.

  • @chrisburton

    I solved the Opauth issue myself. I only had to add my consumer key and secret into the config file and not into any other files like I was doing.

    What exactly did you do differently? I still can't get it to authorize.