Collective #602

Original Source: http://feedproxy.google.com/~r/tympanus/~3/2fZSg2-o7zo/

Inspirational Website of the Week: CUSP

A superb elegant look with very interesting distortion effects. Our pick this week.

Get inspired

Our Sponsor
Start your own freelance business by becoming a Divi expert

Learn how to develop websites with the most popular WordPress theme in the world and secure your success as a freelancer.

Start learning now

Building dark mode on Stack Overflow

Aaron Shekey talks about the work that went into the new dark mode option of Stack Overflow.

Read it

Kontrapunkt Type

Step inside a virtual experience of the solo exhibition ‘Kontrapunkt Type’, presented by design agency Kontrapunkt, DNP and Ginza Graphic Gallery in Tokyo.

Check it out

Watched Box

Heydon Pickering made this declarative container queries solution.

Check it out

Writing an Emulator in JavaScript (and Interfacing with Multiple UIs)

A great guide by Tania Rascia where she shares her journey of writing a Chip-8 interpreter.

Read it

Image Compare Viewer

Compare before and after images, for grading, CGI and other retouching comparisons.

Check it out

Image Techniques On The Web

Ahmad Shadeed’s guide to including images in HTML covering various techniques.

Read it

Stacks

A set of layout components for building React Native views blazingly fast.

Check it out

How && and || Operators Really Work in JavaScript

An in-depth post that explains in examples how exactly && and || operators work in JavaScript.

Read it

Practice time!

Practice your ukulele with this project by Monica Dinculescu.

Check it out

Generative Data Visualization

The third part of a series where Shirley Wu show how to create custom data visualizations using SVG, Vue, and D3.js.

Check it out

Bubble Tape Text

A super cool unrolling scroll effect by Matthew Rayfield.

Check it out

Prog Arp II

An arpeggiator instrument by Jake Albaugh.

Check it out

Creating Morphing Animations with CSS clip-path

Learn how to implement morphing, a technique for transforming one appearance into another, using CSS in this tutorial by Mikael Ainalem.

Read it

How Google Ruined the Internet

Google has become a card catalog that is constantly being reordered by
an angry, misinformed mob.

Read it

Updates to Form Controls and Focus

Microsoft Edge and Google Chrome spent the last year collaborating to retheme and improve the functionality of the built-in form controls on Chromium browsers.

Read it

Meanderer

A JavaScript micro-library for responsive CSS motion paths. Made by Jhey Tompkins.

Check it out

Bongo Cat Codes #2 – Jamming

A lovely animation by Caroline Artz.

Check it out

3D Photography using Context-aware Layered Depth Inpainting

A novel method for converting a single RGB-D input image into a 3D photo.

Check it out

Making a responsive CSS grid layout with just 3 properties

Learn how to pull off a simple responsive template based on CSS Grid.

Read it

Why you should stop using Google Analytics on your website

Here’s a look at why you should remove Google Analytics from your website and help create a more open, independent web that’s more friendly to the visitors.

Read it

From Our Blog
Interactive WebGL Hover Effects

A simple tutorial on how to achieve an interactive mouseover/hover effect on images in some easy steps.

Check it out

Collective #602 was written by Pedro Botelho and published on Codrops.

Burger King's banned ads are a whopper of a mistake

Original Source: http://feedproxy.google.com/~r/CreativeBloq/~3/WelJ8ssy2qs/banned-whopper-ads

Burger King has been forced to stop showing adverts for its new Rebel Whopper burger after the Advertising Standards Authority (ASA) deemed them misleading. Launched in January to coincide with Veganuary (in which people attempt to eat only vegan food for the whole month), the ads proclaimed the new burger to be the chain's "first plant-based burger”. 

However, while the Rebel Whopper may not contain any beef, it soon came to light that it is cooked on the same grill as its meat counterpart. Twitter users spotted the smallprint on the ad, with many taking the fast food giant to task. In reply to countless disgruntled tweets, Burger King claimed this was to preserve the Whopper's "signature flame-grilled taste" – something we doubt is as important to vegetarians as the thing being, you know, vegetarian.

It's safe to say these won't be making our list of the best poster designs any time soon. As well as describing the product as "100% WHOPPER – NO BEEF", the advertising (above) contained a logo proclaiming, "powered by the vegetarian butcher" (which, er, doesn't scream 'not suitable for vegetarians' to us). 

 "So it’s an absolute waste of time then?" Said one Twitter user on learning that the burger is cooked on the same grill as the original Whopper. "What’s the point in bringing out plant based foods that aren’t suitable for even vegetarians?" 

The ASA had beef with several elements of the ads "The presence of the “Vegetarian Butcher” logo, the green colour palette and the timing of the ad and product release to coincide with Veganuary" all contributed to the impression that the product is suitable for vegetarians, claimed the ruling. 

Burger King

Not suitable for vegetarians

Burger King argued that "the small print at the bottom of the ads stated that the Rebel Whopper may not be suitable for vegans or vegetarians as it was cooked alongside other meat products", but this wasn't enough for the ASA. “We concluded that the ads were misleading,” it said. “The ads must not appear again in their current form.” 

Burger King isn't the only fast food chain to have social media trouble lately. McDonald's recently apologised and deleted a 'socially-distanced' version of its logo after a backlash from those who saw it as an opportunistic response to the coronavirus pandemic. At least Burger King has had more success with its ads elsewhere. We were impressed with its recent campaign featuring a mouldy whopper in a clever swipe at McDonald's. It's ironic that, advertising-wise, the chain's mouldy burger left a better taste than its "plant-based" one.

Related articles:

McDonald's posters go viral for all the wrong reasonsThe optical illusion you probably won't want to work outBurger King trolls parliament in cheeky campaign

Thunder is 80s Graphic Design Awesomeness

Original Source: http://feedproxy.google.com/~r/abduzeedo/~3/uUml15yLrc8/thunder-80s-graphic-design-awesomeness

Thunder is 80s Graphic Design Awesomeness
Thunder is 80s Graphic Design Awesomeness

abduzeedoApr 15, 2020

In this time of sorrow and stress there’s nothing better than a boost of pure 80s graphic design inspiration. A lightning of energy directed straight to our hearts to lift us up. Perhaps even get me out of my lazy state and make me open Photoshop and try to recreate that effect. I am talking about the artwork that João Marques designed and shared  for “Thunder”, a long-awaited track from KURA released for free on July 2019. 

The artwork was heavily inspired by old rock and metal vinyl sleeves due to the song’s sampling of AC/DC’s “Thunderstruck”. – Joao Marques

Graphic Design


New Dune logo revealed (and don’t worry, they fixed it)

Original Source: http://feedproxy.google.com/~r/CreativeBloq/~3/fivk5uwmT2g/dune-logo-revealed

The brand new logo for Warner Bros.' new reboot of Frank Herbert's Dune has been released, and it closely matches the controversial title treatment that leaked back in January – with one key difference. Along with the first image from the movie (featuring Timothée Chalamet as Paul Atreides), the new logo first appeared on the film's official Twitter page last night.

The logo uses the four U-shapes in different orientations that we first saw in photographs from a French convention at the start of the year. Back then, the design proved contentious, with many concerned that the leaked logo appeared to read 'DUNC' rather than 'DUNE'. However, that widely-shared concept (below) was in fact a fan rendering based on photographs from the convention, and was missing an all-important lens flare inside the 'E'. Thankfully, said lens flare is present and correct in the new, official logo. Phew.

Looking for ideas? Check out our guide to finding logo design inspiration.

Directed by Denis Villeneuve, Dune is slated for release on 18 December this year. According to its official synopsis, film "tells the story of Paul Atreides, a brilliant and gifted young man born into a great destiny beyond his understanding, who must travel to the most dangerous planet in the universe to ensure the future of his family and his people." An all-star cast features, alongside Chalamet, Zendaya, Oscar Isaac and more.

You can read all about the original leaked logo drama (and enjoy a brilliant pasta-based take on it) here. We're excited to see how Villeneuve makes his stamp on the sci-fi franchise, and, most of all, we're relieved to know that this December, we won't be queueing up to watch 'Dunc'.

Related articles: 

Is this the new Cadbury logo?Iconic logos reimagined for the age of coronavirusThe 10 best logos of all time

Interactive WebGL Hover Effects

Original Source: http://feedproxy.google.com/~r/tympanus/~3/W_A-q9lF8Xc/

I love WebGL, and in this article I will explain one of the cool effects you can make if you master shaders. The effect I want to recreate is originally from Jesper Landberg’s website. He’s a really cool dude, make sure to check out his stuff:

So let’s get to business! Let’s start with this simple HTML:

<div class=”item”>
<img src=”img.jpg” class=”js-image” alt=””>
<h2>Some title</h2>
<p>Lorem ipsum.</p>
</div>
<script src=”app.js”></script>

Couldn’t be any easier! Let’s style it a bit to look prettier:

All the animations will happen in a Canvas element. So now we need to add a bit of JavaScript. I’m using Parcel here, as it’s quite simple to get started with. I’ll use Three.js for the WebGL part.

So let’s add some JavaScript and start with a basic Three.js setup from the official documentation:

import * as THREE from “three”;

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );

var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

camera.position.z = 5;

var animate = function () {
requestAnimationFrame( animate );

cube.rotation.x += 0.01;
cube.rotation.y += 0.01;

renderer.render( scene, camera );
};

animate();

Let’s style the Canvas element:

body { margin: 0; }

canvas {
display: block;
position: fixed;
z-index: -1; // put it to background
left: 0; // position it to fill the whole screen
top: 0; // position it to fill the whole screen
}

Once you have all this in place, you can just run it with `parcel index.html`. Now, you wouldn’t see much, its an empty 3D scene so far. Let’s leave the HTML for a moment, and concentrate on the 3D scene for now.

Let’s create a simple PlaneBufferGeometry object with an image on it. Just like this:

let TEXTURE = new TextureLoader().load(‘supaAmazingImage.jpg’);
let mesh = new Mesh(
new PlaneBufferGeometry(),
new MeshBasicMaterial({map: TEXTURE})
)

And now we’ll see the following:

Obviously we are not there yet, we need that color trail following our mouse. And of course, we need shaders for that. If you are interested in shaders, you’ve probably come across some tutorials on how to displace images, like displacing on hover or liquid distortion effects.

But we have a problem: we can only use shaders on (and inside) that image from the example above. But the effect is not constrained to any image borders, but rather, it’s fluid, covering more area, like the whole screen.

Postprocessing to the rescue

It turns out that the output of the Three.js renderer is just another image. We can make use of that and apply the shader displacement on that output!

Here is the missing part of the code:

// set up post processing
let composer = new EffectComposer(renderer);
let renderPass = new RenderPass(scene, camera);
// rendering our scene with an image
composer.addPass(renderPass);

// our custom shader pass for the whole screen, to displace previous render
let customPass = new ShaderPass({vertexShader,fragmentShader});
// making sure we are rendering it.
customPass.renderToScreen = true;
composer.addPass(customPass);

// actually render scene with our shader pass
composer.render()
// instead of previous
// renderer.render(scene, camera);

There are a bunch of things happening here, but it’s pretty straightforward: you apply your shader to the whole screen.

So let’s do that final shader with the effect:

// get small circle around mouse, with distances to it
float c = circle(uv, mouse, 0.0, 0.2);
// get texture 3 times, each time with a different offset, depending on mouse speed:
float r = texture2D(tDiffuse, uv.xy += (mouseVelocity * .5)).x;
float g = texture2D(tDiffuse, uv.xy += (mouseVelocity * .525)).y;
float b = texture2D(tDiffuse, uv.xy += (mouseVelocity * .55)).z;
// combine it all to final output
color = vec4(r, g, b, 1.);

You can see the result of this in the first demo.

Applying the effect to several images

A screen has its size, and so do images in 3D. So what we need to do now is to calculate some kind of relation of those two.

Just like I did in my previous article, we can make a plane with a width of 1, and fit it exactly to the screen width. So practically, we have WidthOfPlane=ScreenSize.

For our Three.js scene, this means that if want an image with a width of 100px on the screen, we will make a Three.js object with width of 100*(WidthOfPlane/ScreenSize). That’s it! With this kind of math we can also set some margins and positions easily.

When the page loads, I will loop through all the images, get their dimensions, and add them to my 3D world:

let images = […document.querySelectorAll(‘.js-image’)];
images.forEach(image=>{
// and we have the width, height and left, top position of the image now!
let dimensions = image.getBoundingClientRect();
// hide original image
image.style.visibility = hidden;
// add 3D object to your scene, according to its HTML brother dimensions
createMesh(dimensions);
})

Now it’s quite straightforward to make this HTML-3D hybrid.

Another thing that I added here is mouseVelocity. I used it to change the radius of the effect. The faster the mouse moves, the bigger the radius.

To make it scrollable, we would just need to move the whole scene, the same amount that the screen was scrolled. Using that same formula I mentioned before: NumberOfPixels*(WidthOfPlane/ScreenSize).

Sometimes it’s even easier to make WidthOfPlane equal to ScreenSize. That way, you end up with exactly the same numbers in both worlds!

Exploring different effects

With different shaders you can come up with any kind of effect with this approach. So I decided to play a little bit with the parameters.

Instead of separating the image in three color layers, we could simply displace it depending on the distance to the mouse:

vec2 newUV = mix(uv, mouse, circle);
color = texture2D(tDiffuse,newUV);

And for the last effect I used some randomness, to get a pixelated effect around the mouse cursor.

In this last demo you can switch between effects to see some modifications you can make. With the “zoom” effect, I just use a displacement, but in the last one, I also randomize the pixels, which looks kinda cool to me!

I’d be happy to see your ideas for this animation. What kind of effect would you do with this technique?

Interactive WebGL Hover Effects was written by Yuriy Artyukh and published on Codrops.

How to Set Up Basic jQuery Form Validation in Two Minutes

Original Source: https://www.sitepoint.com/basic-jquery-form-validation-tutorial/?utm_source=rss

How to Set Up Basic jQuery Form Validation in Two Minutes

This tutorial shows you how to set up a basic form validation with jQuery, demonstrated by a registration form.

We’re going to use the jQuery Validation Plugin to validate our form. The basic principle of this plugin is to specify validation rules and error messages for HTML elements in JavaScript.

<!–

Here’s a live demo of what we’re going to build:

CodePen LINK GOES HERE

–>

Step 1: Include jQuery

First, we need to include the jQuery library. The jQuery validation plugin has been tested up to jQuery version 3.1.1, but the demo in this article works perfectly with version 3.4.1, which is the latest one.

You can use any of the following download options:

Download it from jquery.com
Download it using Bower: $ bower install jquery
Download it using npm or Yarn: $ npm install jquery or yarn add jquery
Use a CDN: https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js

Create a new HTML file named index.html and include jQuery before the closing </body> tag:

<!– Change the “src” attribute according to your installation path –>
<script src=”vendor/jquery/dist/jquery.min.js”></script>

If you’d like to use Bower or npm but aren’t familiar with them, you might be interested in these two articles:

Package Management for the Browser with Bower
A Beginner’s Guide to npm — the Node Package Manager

Step 2: Include the jQuery Validation Plugin

Choose between:

Download it from the plugin’s github repo
Download it using Bower: $ bower install jquery-validation
Download it using npm: npm i jquery-validation
NuGet: Install-Package jQuery.Validation
Use a CDN: https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/jquery.validate.min.js

Include the plugin after jQuery:

<!– Change the “src” attribute according to your installation path –>
<script src=”vendor/jquery-validation/dist/jquery.validate.min.js”></script>

The post How to Set Up Basic jQuery Form Validation in Two Minutes appeared first on SitePoint.

Top 10 CSS Editors [Review]

Original Source: https://www.hongkiat.com/blog/top-css-editors-reviewed/

CSS is a simple language that it does not need a special editor to write. But having the right code editor will help you minimize errors while writing the CSS code, and overall boost your…

Visit hongkiat.com for full content.

People drew car logos from memory and the results are hilarious

Original Source: http://feedproxy.google.com/~r/CreativeBloq/~3/yl_t5Bml53A/car-logo-drawings

We like to think we're pretty knowledgeable when it comes to logos and branding, but as a new study has shown, drawing even the most recognisable logos from memory can be a tad harder than it looks. 

Vanmonster recently asked 100 members of the British public to draw several famous car logos from memory, and the results range from impressively accurate to hilariously off. They also serve as an interesting insight into which logo elements are ingrained into the public consciousness, and which are more forgettable than the manufacturers might like to think. For some of the most memorable logos ever, check out our best logos of all time.

We'll start with perhaps the simplest logo on Vanmonster's list. Surely Audi's four intersecting rings (below) are impossible to forget? To be fair, the vast majority of entrants got this one right, and most slip-ups are at least ring-related (Audi's and the Olympics' rings are similar, we'll give them that). As for those towards the bottom-right (Vanmoster lists the drawings from 'most accurate' to 'least accurate'), a few seem to have mixed up Audi and the Avengers. They both begin with 'A', we guess.

audi

Most of these look about right

On the other end of the spectrum, the Alfa Romeo logo is probably the most complex on the list. Unsurprising, then, that most got this one wrong. 74% of entrants forgot to include the red cross, 63% forgot the green snake and a whopping 75% didn't include the shield. Our favourites are probably the three 'least accurate': two question marks, and one which simply says, "animals of some sort".

100 very different Alfa Romeo logos

As well as showing all 100 entries for each logo, Vanmonster includes a handy gallery showing us the original logo alongside the most and least accurate attempt. Below are the best and worst attempts at BMW's logo (which recently underwent its biggest design change in over 100 years).

BMW logos

Umm….

You can find the rest of the entries on Vanmonster's website, with logos including Renault, Toyota, Ferrari and many more. One thing's for sure, just like when 150 Americans tried to draw various (non-vehicular) logos from memory, this car logo test proves that the simplest are the most memorable. It's easier to recall rings than flag-snake-shield combinations.

Related articles:

Where to find logo design inspirationQuiz: Can you identify these original car logos?TrueCar rebrand fails to reinvent the wheel

4 Top SEO Plugins For WordPress (+ Bonus Tools)

Original Source: http://feedproxy.google.com/~r/1stwebdesigner/~3/Hhq8pdW-a94/

When building out a WordPress website, it’s vital to have all the right tools on hand. And to get eyeballs on your content, that means building out a solid SEO strategy. A relatively hands-off way to accomplish this is through the use of SEO plugins. Luckily, there are quite a few plugins available for WordPress that make optimizing your site for SEO super easy.

Let’s take a look at some of these SEO plugins for WordPress then dive into discussing a few other tools that can take the guesswork out of selecting keywords and tracking results.

UNLIMITED DOWNLOADS: 500,000+ WordPress & Design Assets

Sign up for Envato Elements and get unlimited downloads starting at only $16.50 per month!

DOWNLOAD NOW

Yoast SEO

Yoast SEO - WordPress SEO plugins

First on our list is Yoast SEO. This WordPress plugin is one of the most popular, for good reason. It acts as a one-stop shop for on-page SEO. Once installed, it automatically adds widgets to each post and page you can use to add SEO titles, descriptions, assign keywords, as well as other items. You can also use it to add Open Graph metadata. Additionally, you can use it to add social media images to each post along with titles and descriptions optimized for social media platforms. Lastly, Yoast creates an XML sitemap for you and can be used for managing SEO redirects. Both a free and premium version of the plugin are available.

SEOPress

SEOPress - WordPress SEO plugins

Another great option is SEOPress. This plugin covers many of the same attributes as Yoast by adding fields for customizing a post or page’s meta title, description, social media content, redirects, and XML sitemaps. It’s interface is a bit easier to navigate, however, while still offering a wider range of options for experienced developers. This plugin is available in a free and premium version as well.

All in One SEO Pack

All In One SEO - WordPress SEO plugins

Still another popular option is the All in One SEO Pack. This SEO plugin for WordPress includes a full set of tools you can implement immediately on your website. Customize meta titles and descriptions; set up an XML sitemap, create image sitemaps, and more. It’s also compatible with WooCommerce. As you might expect, the premium version of this plugin comes with additional features and allows for a greater level of control over your site’s optimization efforts.

Rank Math

RankMath - WordPress SEO plugins

The last of the plugins we’ll be discussing here is Rank Math. This WordPress SEO plugin is super easy to use and makes it easy to optimize your posts and pages for search engines and for social media. Use the provided setup wizard to import information from other SEO plugins or manually customize meta titles, descriptions, and images. Use it to create Open Graph metadata, an XML sitemap, integrate with Google Search Console and more.

Bonus Tools & Resources

Though the primary focus here is SEO plugins for WordPress, we’d be remiss if we didn’t at least mention a few other tools that make building a comprehensive SEO strategy easier.

KeywordTool.io: This simple, straightforward tool delivers keyword suggestions by using Google Autocomplete. It’s as simple as it is genius.
SEOQuake: This browser extension can be used to assess a wide number of on-page SEO variables for any website you visit.
Ahrefs: The ultimate competitor research tools. Ahrefs allows you to see why your competitors are ranking for the keywords they are so you can plan a comparable strategy.
SEMRush: This tools allows you to keep track of how your site is performing as well as monitor competitors, backlinks, and more.
Google Search Console: Last on our list, this tool allows you to research keywords and monitor their ranking on any website you manage.

Pick a WordPress SEO Plugin and Start Ranking

In case you didn’t know, having an SEO strategy is imperative for any site’s success. Sure, some happen upon it accidentally, but most keep a mindful eye on keywords and rankings. And you can take a lot of the legwork out of this effort by using a WordPress SEO plugin and by utilizing some of the research and monitoring tools listed here. The results will be well worth the price of admission, so to speak.


Local Authentication Using Passport in Node.js

Original Source: https://www.sitepoint.com/local-authentication-using-passport-node-js/?utm_source=rss

Local Authentication Using Passport in Node.js

A common requirement when building a web app is to implement a login system, so that users can authenticate themselves before gaining access to protected views or resources. Luckily for those building Node apps, there’s a middleware called Passport that can be dropped into any Express-based web application to provide authentication mechanisms in only a few commands.

In this tutorial, I’ll demonstrate how to use Passport to implement local authentication (that is, logging in with a username and password) with a MongoDB back end. If you’re looking to implement authentication via the likes of Facebook or GitHub, please refer to this tutorial.

As ever, all of the code for this article is available for download on GitHub.

Prerequisites

To follow along with this tutorial, you’ll need to have Node and MongoDB installed on your machine.

You can install Node by heading to the official Node download page and grabbing the correct binaries for your system. Alternatively, you can use a version manager — a program that allows you to install multiple versions of Node and switch between them at will. If you fancy going this route, please consult our quick tip, “Install Multiple Versions of Node.js Using nvm”.

MongoDB comes in various editions. The one we’re interested in is the MongoDB Community Edition.

The project’s home page has excellent documentation and I won’t try to replicate that here. Rather, I’ll offer you links to instructions for each of the main operating systems:

Install MongoDB Community Edition on Windows
Install MongoDB Community Edition on macOS
Install MongoDB Community Edition on Ubuntu

If you use a non-Ubuntu–based version of Linux, you can check out this page for installation instructions for other distros. MongoDB is also normally available through the official Linux software channels, but sometimes this will pull in an outdated version.

Note: You don’t need to enter your name and address to download MongoDB. If prompted, you can normally dismiss the dialog.

If you’d like a quick refresher on using MongoDB, check out our beginner’s guide, “An Introduction to MongoDB”.

Authentication Strategies: Session vs JWT

Before we begin, let’s talk briefly about authentication choices.

Many of the tutorials online today will opt for token-based authentication using JSON Web Tokens (JWTs). This approach is probably the simplest and most popular one nowadays. It relegates part of the authentication responsibility to the client and makes them sign a token that’s sent with every request, to keep the user authenticated.

Session-based authentication has been around longer. This method relegates the weight of the authentication to the server. It uses cookies and sees the Node application and database work together to keep track of a user’s authentication state.

In this tutorial, we’ll be using session-based authentication, which is at the heart of the passport-local strategy.

Both methods have their advantages and drawbacks. If you’d like to read more into the difference between the two, this Stack Overflow thread might be a good place to start.

Creating the Project

Once all of the prerequisite software is set up, we can get started.

We’ll begin by creating the folder for our app and then accessing that folder on the terminal:

mkdir AuthApp
cd AuthApp

To create the node app, we’ll use the following command:

npm init

You’ll be prompted to provide some information for Node’s package.json. Just keep hitting Return to accept the default configuration (or use the -y flag).

Setting up Express

Now we need to install Express. Go to the terminal and enter this command:

npm install express

We’ll also need to install the body-parser middleware which is used to parse the request body that Passport uses to authenticate the user. And we’ll need to install the express-session middleware.

Let’s do that. Run the following command:

npm install body-parser express-session

When that’s done, create an index.js file in the root folder of your app and add the following content to it:

/* EXPRESS SETUP */

const express = require(‘express’);
const app = express();

app.use(express.static(__dirname));

const bodyParser = require(‘body-parser’);
const expressSession = require(‘express-session’)({
secret: ‘secret’,
resave: false,
saveUninitialized: false
});

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(expressSession);

const port = process.env.PORT || 3000;
app.listen(port, () => console.log(‘App listening on port ‘ + port));

First, we require Express and create our Express app by calling express(). Then we define the directory from which to serve our static files.

The next line sees us require the body-parser middleware, which will help us parse the body of our requests. We’re also adding the express-session middleware to help us save the session cookie.

As you can, see we’re configuring express-session with a secret to sign the session ID cookie (you should choose a unique value here), and two other fields, resave and saveUninitialized. The resave field forces the session to be saved back to the session store, and the saveUninitialized field forces a session that is “uninitialized” to be saved to the store. To learn more about them, check out their documentation, but for now it’s enough to know that for our case we want to keep them false.

Then, we use process.env.PORT to set the port to the environment port variable if it exists. Otherwise, we’ll default to 3000, which is the port we’ll be using locally. This gives you enough flexibility to switch from development, directly to a production environment where the port might be set by a service provider like, for instance, Heroku. Right below that, we called app.listen() with the port variable we set up and a simple log to let us know that it’s all working fine and on which port is the app listening.

That’s all for the Express setup. Now it’s on to setting up Passport.

Setting up Passport

First, we install Passport with the following command:

npm install passport

Then we need to add the following lines to the bottom of the index.js file:

/* PASSPORT SETUP */

const passport = require(‘passport’);

app.use(passport.initialize());
app.use(passport.session());

Here, we require passport and initialize it along with its session authentication middleware, directly inside our Express app.

Creating a MongoDB Data Store

Since we’re assuming you’ve already installed Mongo, you should be able to start the Mongo shell using the following command:

mongo

Within the shell, issue the following command:

use MyDatabase;

This simply creates a datastore named MyDatabase.

Leave the terminal there; we’ll come back to it later.

Connecting Mongo to Node with Mongoose

Now that we have a database with records in it, we need a way to communicate with it from our application. We’ll be using Mongoose to achieve this. Why don’t we just use plain Mongo? Well, as the Mongoose devs like to say on their website:

writing MongoDB validation, casting and business logic boilerplate is a drag.

Mongoose will simply make our lives easier and our code more elegant.

Let’s go ahead and install it with the following command:

npm install mongoose

We’ll also be using passport-local-mongoose, which will simplify the integration between Mongoose and Passport for local authentication. It will add a hash and salt field to our Schema in order to store the hashed password and the salt value. This is great, as passwords should never be stored as plain text in a database.

Let’s install the package:

npm install passport-local-mongoose

Now we have to configure Mongoose. Hopefully you know the drill by now: add the following code to the bottom of your index.js file:

/* MONGOOSE SETUP */

const mongoose = require(‘mongoose’);
const passportLocalMongoose = require(‘passport-local-mongoose’);

mongoose.connect(‘mongodb://localhost/MyDatabase’,
{ useNewUrlParser: true, useUnifiedTopology: true });

const Schema = mongoose.Schema;
const UserDetail = new Schema({
username: String,
password: String
});

UserDetail.plugin(passportLocalMongoose);
const UserDetails = mongoose.model(‘userInfo’, UserDetail, ‘userInfo’);

Here we require the previously installed packages. Then we connect to our database using mongoose.connect and give it the path to our database. Next, we’re making use of a Schema to define our data structure. In this case, we’re creating a UserDetail schema with username and password fields.

Finally, we add passportLocalMongoose as a plugin to our Schema. This will work part of the magic we talked about earlier. Then, we create a model from that schema. The first parameter is the name of the collection in the database. The second one is the reference to our Schema, and the third one is the name we’re assigning to the collection inside Mongoose.

That’s all for the Mongoose setup. We can now move on to implementing our Passport strategy.

Implementing Local Authentication

And finally, this is what we came here to do! Let’s set up the local authentication. As you’ll see below, we’ll just write the code that will set it up for us:

/* PASSPORT LOCAL AUTHENTICATION */

passport.use(UserDetails.createStrategy());

passport.serializeUser(UserDetails.serializeUser());
passport.deserializeUser(UserDetails.deserializeUser());

There’s quite some magic going on here. First, we make passport use the local strategy by calling createStrategy() on our UserDetails model — courtesy of passport-local-mongoose — which takes care of everything so that we don’t have to set up the strategy. Pretty handy.

Then we’re using serializeUser and deserializeUser callbacks. The first one will be invoked on authentication, and its job is to serialize the user instance with the information we pass on to it and store it in the session via a cookie. The second one will be invoked every subsequent request to deserialize the instance, providing it the unique cookie identifier as a “credential”. You can read more about that in the Passport documentation.

Routes

Now let’s add some routes to tie everything together. First, we’ll add a final package. Go to the terminal and run the following command:

npm install connect-ensure-login

The connect-ensure-login package is middleware that ensures a user is logged in. If a request is received that is unauthenticated, the request will be redirected to a login page. We’ll use this to guard our routes.

Now, add the following to the bottom of index.js:

/* ROUTES */

const connectEnsureLogin = require(‘connect-ensure-login’);

app.post(‘/login’, (req, res, next) => {
passport.authenticate(‘local’,
(err, user, info) => {
if (err) {
return next(err);
}

if (!user) {
return res.redirect(‘/login?info=’ + info);
}

req.logIn(user, function(err) {
if (err) {
return next(err);
}

return res.redirect(‘/’);
});

})(req, res, next);
});

app.get(‘/login’,
(req, res) => res.sendFile(‘html/login.html’,
{ root: __dirname })
);

app.get(‘/’,
connectEnsureLogin.ensureLoggedIn(),
(req, res) => res.sendFile(‘html/index.html’, {root: __dirname})
);

app.get(‘/private’,
connectEnsureLogin.ensureLoggedIn(),
(req, res) => res.sendFile(‘html/private.html’, {root: __dirname})
);

app.get(‘/user’,
connectEnsureLogin.ensureLoggedIn(),
(req, res) => res.send({user: req.user})
);

At the top, we’re requiring connect-ensure-login. We’ll come back to this later.

Next, we set up a route to handle a POST request to the /login path. Inside the handler, we use the passport.authenticate method, which attempts to authenticate with the strategy it receives as its first parameter — in this case local. If authentication fails, it will redirect us to /login, but it will add a query parameter — info — that will contain an error message. Otherwise, if authentication is successful, it will redirect us to the ‘/’ route.

Then we set up the /login route, which will send the login page. For this, we’re using res.sendFile() and passing in the file path and our root directory, which is the one we’re working on — hence the __dirname.

The /login route will be accessible to anyone, but our next ones won’t. In the / and /private routes we’ll send their respective HTML pages, and you’ll notice something different here. Before the callback, we’re adding the connectEnsureLogin.ensureLoggedIn() call. This is our route guard. Its job is validating the session to make sure you’re allowed to look at that route. Do you see now what I meant earlier by “letting the server do the heavy lifting”? We’re authenticating the user every single time.

Finally, we’ll need a /user route, which will return an object with our user information. This is just to show you how you can go about getting information from the server. We’ll request this route from the client and display the result.

Talking about the client, let’s do that now.

The post Local Authentication Using Passport in Node.js appeared first on SitePoint.