W
Waspβ€’6d ago
Amar

User Auth from external API

I am building a fullstack project in Wasp (v.0.16.3) with React for website UI and Flutter for its mobile app version. I want to use the API endpoints in wasp project to access the user authentication and database related functaionalities from external client (postman or mobile app). So far I have implemented a dummy custom API endpoint to get a simple json greeting message from the wasp backend. I am using email-password authentication. But I am stuck on how to implement login, signup, and other auth related end points. Thank you for your kind interest in my problem πŸ™
No description
No description
3 Replies
kapa.ai
kapa.aiβ€’6d ago
Hi @Amar. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Currently, Wasp doesn't have a built-in way to expose authentication APIs for external clients like mobile apps. The authentication system in Wasp is designed primarily for web applications using its internal RPC mechanism. However, you can implement a workaround by creating custom API endpoints that handle authentication. Here's how you might approach this: Creating Custom Auth API Endpoints You'll need to create custom HTTP endpoints that handle login and signup functionality. These endpoints would use the same underlying authentication logic that Wasp uses internally. For example, you could create a custom API endpoint for login:
// in your main.wasp file
api loginApi {
httpRoute: (POST, "/api/login"),
fn: import { loginHandler } from "@src/auth/loginHandler.js",
auth: false
}

// in src/auth/loginHandler.js
import { prisma } from 'wasp/server'
import { createSessionAndCookie } from 'wasp/auth'
import bcrypt from 'bcrypt'
export const loginHandler = async (req, res) => {
try {
const { username, password } = req.body

// Find the user
const user = await prisma.user.findUnique({ where: { username } })
if (!user) {
return res.status(401).json({ message: 'Invalid credentials' })
}

// Verify password
const passwordValid = await bcrypt.compare(password, user.password)
if (!passwordValid) {
return res.status(401).json({ message: 'Invalid credentials' })
}

// Create session and get token
const { sessionId } = await createSessionAndCookie(req, res, user.id)

// Return token that mobile app can store
return res.json({
token: sessionId,
user: {
id: user.id,
username: user.username
// other user fields you want to return
}
})
} catch (error) {
return res.status(500).json({ message: 'Server error' })
}
}
// in your main.wasp file
api loginApi {
httpRoute: (POST, "/api/login"),
fn: import { loginHandler } from "@src/auth/loginHandler.js",
auth: false
}

// in src/auth/loginHandler.js
import { prisma } from 'wasp/server'
import { createSessionAndCookie } from 'wasp/auth'
import bcrypt from 'bcrypt'
export const loginHandler = async (req, res) => {
try {
const { username, password } = req.body

// Find the user
const user = await prisma.user.findUnique({ where: { username } })
if (!user) {
return res.status(401).json({ message: 'Invalid credentials' })
}

// Verify password
const passwordValid = await bcrypt.compare(password, user.password)
if (!passwordValid) {
return res.status(401).json({ message: 'Invalid credentials' })
}

// Create session and get token
const { sessionId } = await createSessionAndCookie(req, res, user.id)

// Return token that mobile app can store
return res.json({
token: sessionId,
user: {
id: user.id,
username: user.username
// other user fields you want to return
}
})
} catch (error) {
return res.status(500).json({ message: 'Server error' })
}
}
Similarly, you would create an endpoint for signup. Using the API from External Clients Once you have these endpoints, you can call them from your Flutter app or Postman:
POST /api/login
Content-Type: application/json

{
"username": "[email protected]",
"password": "yourpassword"
}
POST /api/login
Content-Type: application/json

{
"username": "[email protected]",
"password": "yourpassword"
}
As mentioned in the Discord support thread, this is a workaround since Wasp doesn't officially expose authentication APIs for external clients yet: Discord support thread mentions: "Unfortunately, Wasp doesn't yet expose the API for authenticating users (the idea is to use its internal RPC, which doesn't make sense for your use case)." Using the API from Your Client For your web client, you can use the Axios wrapper from Wasp to make API calls:
import { api } from "wasp/client/api";
async function fetchCustomRoute() {
const res = await api.get("/foo/bar");
console.log(res.data);
}
import { api } from "wasp/client/api";
async function fetchCustomRoute() {
const res = await api.get("/foo/bar");
console.log(res.data);
}
As shown in the Using the API from the Client documentation. Limitations This approach has some limitations: - You'll need to handle token storage and management in your Flutter app - You won't get the same seamless experience as with Wasp's built-in auth in the web app - You'll need to implement additional endpoints for other auth features like password reset The Wasp team is aware of this limitation, and better support for mobile authentication might be added in the future. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @Amar, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
genyus
genyusβ€’5d ago
@Amar this example repo from @miho demonstrates how to authenticate externally: https://github.com/wasp-lang/wasp-expo-app It’s written for Expo, but should be enough to illustrate how you can implement auth in Flutter.
GitHub
GitHub - wasp-lang/wasp-expo-app: Example of using Wasp's auth and ...
Example of using Wasp's auth and API in an Expo mobile app - wasp-lang/wasp-expo-app
Amar
AmarOPβ€’5d ago
Thanks @genyus , I'll try to immitate this functaionality in my app. Let's see it goes. Thanks again πŸ™

Did you find this page helpful?