Logout Security

After building a login system, there are still a few considerations to take into account. Authorizing each endpoint is a good way to make sure that only logged-in users have access to the web app. Securing logout is also imperative, especially on shared computers.

When a user clicks the logout button, it’s common to redirect them to a publicly-accessible page. However, what happens when he or she (or the next person to use the computer) clicks the browser’s back button? Chances are that the browser has a locally-cached version of content that should no longer be available now that the user has logged out. Fixing this is pretty simple–just add the following headers to the response for each page with authorized data:

response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = 0

These headers (for HTTP 1.1, HTTP 1.0, and proxies, respectively) tell the browser (and any proxy) not to cache this response. And that’s it! Now if a user logs out then navigates through the browser history, any authorized page (i.e. any page that was sent with the headers above) will not be displayed. (Ideally, navigation to those pages when logged out would trigger a redirect to the login page.) And for most web applications, there shouldn’t be a noticeable performance hit–if there is, the time-loading tradeoff should be well worth the security benefit.

Have any other security tips for logging in or out of a web application? Let me know in the comments below!

Happy coding!
Ryan from The Bunch

Use Case: LunchBunch at the Office

buildings

LunchBunch can be just as useful in the office as it is on a university campus. When it comes to meals, there are a lot of similarities between users in these demographics–both tend to have schedules that change day-to-day, it’s hard to keep track of friends’ availability, and it’s often difficult to organize meals.

Group Emails

Group emails are great for getting information out to many coworkers, but they get disorganized very quickly. Some people might reply to the sender only, others click “reply all”, and they’re hard to search through. It’s difficult to keep track of RSVPs and make sure everyone has the most-recent information when using email to organize a meal. And if you join an email chain late, it takes too long to get caught up. With LunchBunch, everyone is on the same page (pun intended) with easy access to the time, location, and RSVPs for lunch. Sending messages to everyone is easy, and it’s much easier to search through than an email chain. And adding someone to the invitation is a breeze. With just a few taps, any of your Buddies can view the invitation.

Know when Coworkers are Busy

Sometimes it’s tough to know when coworkers are busy and shouldn’t be interrupted. When you’re ready to eat, you don’t need to interrupt anyone’s work to see who’s available. Instead, simply start broadcasting on LunchBunch, and when everyone is at a good stopping point and ready for a lunch break, you can create an invitation. Alternatively, you don’t even need to wait until everyone is hungry–you can create the invitation and add Buddies whenever you’re ready (even if they’re not broadcasting yet).

New People

If your office/building/block is large enough, lunch can be a great way to network with people you otherwise might not meet. You can connect with these people on LunchBunch and organize them into Bunches. You can even schedule times in advance to plan your networking meals at the beginning of each week.

New Places

Whether you’re eating with the same coworkers or networking with new people each day, it’s nice to switch up the location. We’re currently working on a few new features for LunchBunch that will help you find new places nearby, so stay tuned for future updates!

So next time you’re hungry at work and don’t know who’s available, check LunchBunch!

How do you use LunchBunch at work? Do you have suggestions for how we could make LunchBunch even better for your office? Please let us know in the comments below!

Sincerely,
Ryan from The Bunch

Authorization Decorators

Last time I wrote about decorators, I explained their usefulness in rate limiting API endpoints. Today, I’m demonstrating another common use: authorization.

If you store the usernames of logged-in users in the session, your endpoint and decorator might look something like this:

@app.route("/get_secret", methods=["GET"])
@login_required
def secret_info():
    return "The truth is...I am Iron Man."

def login_required(func):
    def login_wrapper(*args, **kwargs):
        if not flask.session.get("username"):
            return "Unauthorized", 401
        return func(*args, **kwargs)
    return login_wrapper

That’s it! Just add @login_required to any endpoint at which you want to restrict access. It’s likely that you’ll want to do something more complex–maybe different users have different roles, or there are other attributes to check–but the concepts will be the same. There are good libraries for integrating HTTP Basic Authentication into your API which is another useful authentication method.

What authentication decorators do you use in your applications? Let me know in the comments below!

Happy coding!
Ryan from The Bunch

Use Case: College Students

university

YOICO–You’re Only In College Once. I did my best to popularize this phrase at The University of Delaware when YOLO was a big deal. YOICO was a great excuse to get a pizza and watch a movie at 3am instead of studying, and the only downside (obviously there aren’t others…) is that I can’t use it anymore now that I’ve graduated.

College is fun, and having the freedom to manage your own time is great. However, sometimes flexible schedules can make it difficult to meet up with people–especially for meals. If I had LunchBunch in college, I would have used it every day.

Eating Alone

Sometimes you only have 5 minutes to eat before class starts or you just want to eat alone, but usually eating with people is more fun. Schedules change every day, but LunchBunch makes it easy to find hungry friends. Instead of texting all of your friends to see who is available, you can check LunchBunch for the friends who–just like you–are ready to eat.

Regular Groups

LunchBunch is great for finding people right now, but it is also useful for regular meals. Let’s say you and your roommates always get lunch together on Tuesdays. You can create a Roommate bunch in the app, and when you’re ready to eat, you can invite all of them at the same time.

Availability

With LunchBunch, you don’t have to worry about messaging people who aren’t available. Sometimes it’s hard to text people before a meal because they might not respond immediately, they may have already eaten, or they’re otherwise not available. When I don’t get an immediate response to a text message, I wonder how long I should wait before asking someone else or going alone. But with LunchBunch, I can see which friends want to eat now, and it’s super easy for me to suggest a place.

So next time you’re hungry, whether you’re getting out of class, you need a study break, or you simply want to see if anyone is available, check LunchBunch!

How do you use LunchBunch in college? Do you have suggestions for how we could make LunchBunch even better for your campus? Please let us know in the comments below!

And remember, you may only be in college once, but YCALB (You Can Always LunchBunch)!

Sincerely,
Ryan from The Bunch

Salts and Hashes

For the past few years, “123456” and “password” have been the top two most-common online passwords. Storing passwords securely is very important for any application–not only to protect the users’ accounts from unauthorized access, but also to protect the passwords themselves. Because many people use the same passwords for multiple applications, a security breach on one site could have ramifications for other sites all over the internet. There are many methods used to protect passwords from getting into the wrong hands, and salts and hashes are two of them.

A hash function converts a user’s password to a string of fixed length from which the original text cannot be recovered. That is, if the password “qwerty” (surprise–another common password!) maps to “QmFzZTY0IGlzIG5vdCBhIGhhc2ggZnVuY3Rpb24hIQ==”, there is no way to recover “qwerty” given the hash function output. So by storing the hash instead of the original password, the security of the database is improved substantially, because even if this hash is compromised, whoever has it won’t be able to recover the original password.

Sounds good, right? Yes, but there’s still more to do. If an unauthorized person gets the hash, he or she can use our hash function on random strings and compare that output to this hash. By testing common passwords, there’s a good chance that the unauthorized individual will try “qwerty” and notice that the hashes match. (Note: It’s possible that two different inputs will map to the same hash, but this is very unlikely.) This is where salts come in handy. A salt is data that is added to the input text before it is hashed. So let’s say that the password is “qwerty” and the salt is “c2FsdA==”. Now, the hash function is run on “qwertyc2FsdA==”, which should have an output distinct from the the hash of “qwerty”. An unauthorized person needs to know the salt in order to test common passwords or use rainbow tables.

There are a plethora of hash functions available, but they are not all created equal. I feel that it’s important to note that Base64 is not a hash function. Contrary to hashes, any Base64-encoded string can be decoded to recover the original text. But there also are true hash functions that aren’t secure. Bcrypt is a good place to start.

Happy coding!
Ryan from The Bunch

Lunch–Hold the Bunch

I have known about LunchBunch since the day its development started—even before that, really, when its concept was one outcome of several days of brainstorming between Matt, Ryan, and Brandon (The Bunch) early last April. I must admit, however, that I have not loved LunchBunch since the day it started. (Which is probably bad, considering Matt is my fiancé.)

I had my hesitations. From the moment the idea first sprung into existence, to the moment I saw the beta-testing release, even until the moment that the live app was on my phone and in my hands—I was hesitant. I was not hesitant that LunchBunch would succeed and be used by many people—only that it would be used by me.

Ask Matt, and he will tell you that throughout the development of LunchBunch, I have been both his biggest fan and his most annoying critic. I was skeptical.

“My friends won’t use LunchBunch.”

“My school is too small, and we only have one place to eat. We usually just walk in and find somebody.”

“I usually eat by myself if I only have a few minutes in between classes.”

I wouldn’t call myself Negative Nancy, but I wanted to be sure that LunchBunch would achieve what it needed to for the audience it was meant to. Some days I didn’t like the colors; some days I thought the swiping function between screens was too slow. (In fact, the last time I was with Matt, he confessed that he only asks me about LunchBunch when he is feeling particularly open-minded and patient.)

The date was November 10, 2015, and LunchBunch had been available for download for three days–-but I hadn’t used it yet. “It isn’t practical for me,” I thought. It was 5:00pm, and I was hungry—but it was dark, raining and I was considering eating microwave popcorn for dinner instead of walking six cold, lonely minutes to the Dining Commons at school.

Then, it occurred to me that now would be the perfect time to try this LunchBunch thing. I started broadcasting to my mere 12 buddies, and to my surprise, three of them were also broadcasting. I wrote an invitation for 5:07pm at the Dining Commons, and suddenly, I was eating a meal with eight friends—all because of LunchBunch. That night, not only were we eating a meal initiated by LunchBunch, but so were at least two other groups of people in the same room!

Since the launch of LunchBunch, I have been the recipient of admiration, applause, and constructive criticism on behalf of The Bunch, and it has been incredible to see people all over using something on their personal phones that The Bunch dreamt of, created and now actually exists. Thanks to LunchBunch, people are easily partaking in meals together, and enjoying one of the most valuable aspects of community—whether that is in a large corporation or a small university (or anything in between).

Happy LunchBunching!

Sincerely,
Megan (kind of) from The Bunch

HTTP Verbs

APIs often support different methods (HTTP verbs) that communicate to the client/server what kind of action is taken at that endpoint. The two most common methods are GET and POST. There are several others (PUT, DELETE, HEAD, OPTIONS, TRACE, CONNECT), but we’re going to focus on GET and POST today.

Endpoints that employ GET do exactly that–they get information from the server and return the results to the requester. Endpoints that use POST usually make changes to the backend in some way–inserting, updating, or deleting something in the database for example. GET is called an idempotent method because its effect on the backend is the same whether the endpoint is hit once or multiple times. This can be true for POST requests too (e.g. /logout where username=”broberts” can be called one time or 100 times, and broberts–and only broberts–will be logged out), but in general, POST is not an idempotent method. RESTful APIs are stateless, so if you use GET at one endpoint, you should get the same response if you hit that endpoint again with the same parameters.

It’s important to note that HTTP methods don’t have special properties–from a functionality standpoint, anything you can do with GET you can do with POST (and vice versa). But that doesn’t mean that you should. One of the reasons it’s good not to make all your endpoints use GET is link prefetching. Browsers might prefetch pages (any GET request) that it thinks a user will visit soon. If your logout endpoint is prefetched, then users’ browsers might be logging them out via link prefetching as soon as they log in!

For more information, W3Schools has some great documentation that provides a closer look at the differences between GET and POST.

Happy coding!
Ryan from The Bunch

Productivity Tools

tools

Teamwork requires effective communication, clear divisions of responsibility, and efficient workflows. When it comes to productivity tools, there are so many options that sometimes more work can be put into picking the right one than into actually completing the project! I’ve put together a list of three great tools that could make your next project a little bit easier to manage. Hopefully, it helps to narrow your search!

Trello

Whether you are working solo, with a partner, or with a whole team, Trello breaks down projects into tasks that are easy to manage and track. The online interface and mobile app feature a board containing lists. You create a card for each task and place it in the list associated with that task. For example, LunchBunch has a list for new features. Some cards on that list might be “Add Buddy from Contacts” and “Emoji Support”. Users can add a description and due date to the card, and anyone on the team can comment on the card to share their thoughts. Cards can be assigned to a user to make it easy to see who is responsible for which tasks. The card owner creates checklists to update as the task nears completion. Trello is very easy to use and great for keeping projects on track.

Google Apps for Work

Gmail is the most-popular email service in the world, and Google Apps for Work allows you to use Gmail with your own domain name which gives your business a more-professional appearance. While the pricing is worth it for that reason alone, it also comes with 30GB of Google Drive space and a bunch of other integrations that come with Gmail accounts. For example, included are Google Hangouts (which is great for internal meetings and meetings outside of your company), Google Calendar, and Google Docs. Google Docs documents, spreadsheets, presentations, forms, and drawings don’t count towards your 30GB of Drive storage, which is a nice bonus!

You can use Google Voice with your account as well. Google Voice gives you a phone number (for free!) that you can attach to your existing work, home, and/or cell phone(s). You can schedule different phones to ring and configure multiple voicemail greetings depending on the time of day, who’s calling, etc.

Google Apps for Work is a must-have for any small business, and Google Voice is a nice feature to separate personal and work calls.

Slack

Of all the tools we use at LunchBunch, Slack is my favorite. “Slack is a messaging app for teams that is on a mission to make your working life simpler, more pleasant, and more productive.” This is how Slack describes itself on its website, and I think that sums it up very well. Communication is organized in channels. So your business might have separate channels for marketing, sales, design, and development. This way, team members can join discussions that they need to be part of, and all of the messages stay organized.

Slack also offers features for sharing files and has plenty of third-party integrations–including Trello and Google Apps for Work–which make it a powerful service. The desktop application and mobile app make team communication extremely efficient. Additionally, the free tier is remarkably generous, and it doesn’t expire.

 
A list of only three services is pretty short, but I think these are great solutions for teams of all sizes and needs. Do you have any favorite tools your team likes to use? Let me know in the comments below!

Sincerely,
Ryan from The Bunch

Rate-Limiting Decorators

Decorators are great for APIs because they cleanly abstract shared functionality from different endpoints. Rate limiting is a great use case for decorators and should be incorporated into just about every API. Rate limiting ensures that there aren’t too many calls originating from the same user/IP address/etc. in a given timeframe. This can prevent the server or database from getting bogged down with spammy requests.

Let’s look at an example. Your application is a math API and has an endpoint /get_fibonacci for computing the nth element of the Fibonacci sequence. This is a computationally expensive operation, and you know that users don’t need to hit this endpoint more than a few times per day. That is, if a user is calling it multiple times in a short window, either there’s an error in the application that is causing that function to be called many times, or the user is abusing the API. Either way, the overloaded server is doing more work than is necessary, and we can prevent this with rate limiting.

To be safe, let’s allow each user call this endpoint 10 times every 5 minutes. If we only expect 2 or 3 calls every 24 hours, this should be plenty, and legitimate users won’t be locked out. If the application has a login system, you can limit based on username. Otherwise, IP address, user agent, or some other identifying data will work. You will need to store a dictionary that maps each user to the number of calls in the past 5 minutes. If you are looking for code to use in your project, you might want to check out a complete example (← code snippet uses Flask).

For an easier code example, let’s say we want to limit API calls by time of day instead of rate–calls are allowed only between midnight and noon. (There’s a use case for that, right?…🙂) This would be our code:

@app.route("/get_fibonacci", methods=["GET"])
@ratelimit
def fibonacci():
    n = int(flask.request.args["n"])
    a = 0
    b = 1
    while b < n:
        a = b
        b = a + b
    return str(b)

def ratelimit(func):
    def ratelimit_wrapper(*args, **kwargs):
        if datetime.datetime.utcnow().time().hour > 12:
            return "Sorry, please try again tomorrow in the AM!"
        return func(*args, **kwargs)
    return ratelimit_wrapper

Then navigate to {host}/get_fibonacci?n=5 to see it in action.

This means that before the given Fibonacci number is computed, the decorator checks to see if the current time is before or after noon. If it’s after noon, the error message is returned to the user. Otherwise, the fibonacci() function runs and returns the result to the requester.

Here’s a line-by-line description of everything that’s going on:

  • 1. This function can be accessed via GET at {host/application_root}/get_fibonacci
  • 2. Attaches the ratelimit decorator to this endpoint (more accurately, it wraps this function with the ratelimit function)
  • 3. Function definition
  • 4. Extract GET parameter from the URL
  • 5/6. Initialize first two elements of the Fibonacci sequence
  • 7. Repeat until we find the nth element
  • 8/9. Get the next element in the sequence
  • 10. Return the nth element (View function expects a string response)
  • 12. Decorator definition
  • 13. Wrapper function that surrounds the decorator–accepts any arguments
  • 14. Check the time in case it’s after noon
  • 15. This is returned to the requester without ever calling fibonacci() if it’s after noon
  • 16. It’s before noon, so return the output of the original function
  • 17. Return this decorator wrapper

Decorators can be confusing at first, but they’re powerful and great for writing simple, clean code. If you have any questions, please let me know in the comments below!

Happy coding!
Ryan from The Bunch

LunchBunch Dictionary

dictionary

When you’re learning something new, sometimes it’s nice to have a cheat sheet to reference, so we’ve compiled a list of some LunchBunch terms to help you keep track. Some of these terms are self-explanatory, but we included them for completeness and to make you aware of all of the current features.

  • Buddy: Users you are connected with in LunchBunch. To become buddies, one of you must send the other a buddy request, and the other must accept it.
  • Bunch: Buddies are organized into bunches. A bunch can have one or more members, and no one can see your bunches except for you. When you broadcast or create an invitation, you can select bunches and/or buddies, so bunches make it easier to choose multiple buddies quickly.
  • Broadcast: When you are hungry, you use broadcasting to let specific bunches/buddies know. In order to see who else is hungry, three conditions need to be met: 1.) you must be buddies, 2.) you must both be hungry, and 3.) you must both be broadcasting to each other. This means that buddies you aren’t broadcasting to will never see that you are hungry. When selecting bunches to broadcast to, you can lock or hide individual buddies. Locking and hiding buddies allows you to override bunch selection.
    • Locked Buddy: This buddy will be broadcast to–even if he or she isn’t a member of a selected bunch.
    • Hidden Buddy: This buddy will not be broadcast to–even if he or she is a member of selected bunch.
  • Invitation: Sending an invitation initiates a message thread for organizing a meal. Invited members can RSVP, send messages, and modify the invitation (unless it is locked).
    • RSVP: Invitation members can RSVP “going” or “not going”, which will automatically send a message to the invitation members. To see who is going, you can scroll through past messages or check the invitation members list where their RSVPs are listed.
    • Message: Text messages (with emoji support! 🎉 🙌) can be sent between invitation members for communication beyond RSVP–location details, etc. or just chatting! Automatic messages are sent when members RSVP, when the time/location of the invitation is modified, and when users are added to the invitation.
    • Modify Invitation: Assuming that the user who created the invitation didn’t lock it, invitation members can change the time and/or location of the invitation and/or invite other users. Only buddies can be added to an invitation, but they do not need to be buddies with everyone in the invitation.
    • Locked Invitation: When you create an invitation, you have the option to lock it to prevent members from editing details. If you lock an invitation, only you can change the time, location, and invitee list. You can also lock/unlock an invitation after you create it.

Still have questions? Is there another term we should add? Please let us know in the comments below!

Sincerely,
Ryan from The Bunch