With the blog live, I still had to publish posts by hand-editing a database seed. This time around I decided to add a proper admin page.
I didn't want to build (or secure) my own password system, so I used OAuth: instead of handing a password to my own app, GitHub authenticates me and vouches for me. I wired it up with Auth.js. GitHub handles the authentication, Auth.js uses that validation to generate an auth session cookie to provide access.
Since I'm the only author, I don't need real user accounts. That's a few lines:
callbacks: {
signIn({ profile }) {
const login = (profile as { login?: string })?.login?.toLowerCase();
return login === "jrflynn3"; // only I get through
},
},
The "Sign in with GitHub" button is public, but anyone else gets bounced the instant GitHub hands them back.
The blog reads by querying the database directly inside server components — no API layer, because the server is already there. Writing a post is different: the data starts in my browser form, and the browser can't (and shouldn't) touch the database — those credentials live only on the server.
So a new post crosses to the server through a Route Handler (POST /api/posts) that re-checks my session, validates the input, and creates the record.
This was my first foray into using OAuth and NextAuth and it wasn't too bad. There was a bit of a learning curve on some of the process - how the GitHub auth layer differed from NextAuth, and how each were necessary for securing access.
Next up is probably going to be some hardening of the site.