ГрапхКЛ је популарна алтернатива традиционалној РЕСТфул АПИ архитектури, која нуди флексибилан и ефикасан језик за упите података и манипулацију за АПИ-је. Са својим растуће усвајање, постаје све важније дати приоритет безбедности ГрапхКЛ АПИ-ја како би заштитили апликације од неовлашћеног приступа и потенцијалних података кршења.
Један ефикасан приступ за обезбеђивање ГрапхКЛ АПИ-ја је имплементација ЈСОН веб токена (ЈВТ). ЈВТ-ови обезбеђују сигуран и ефикасан метод за одобравање приступа заштићеним ресурсима и извођење овлашћених радњи, обезбеђујући безбедну комуникацију између клијената и АПИ-ја.
Аутентификација и ауторизација у ГрапхКЛ АПИ-јима
за разлику од РЕСТ АПИ-ји, ГрапхКЛ АПИ-ји обично имају једну крајњу тачку која омогућава клијентима да динамички захтевају различите количине података у својим упитима. Иако је ова флексибилност њена снага, она такође повећава ризик од потенцијалних безбедносних напада као што су рањивости у контроли приступа.
Да бисте ублажили овај ризик, важно је имплементирати робусне процесе аутентификације и ауторизације, укључујући правилно дефинисање дозвола за приступ. На тај начин гарантујете да само овлашћени корисници могу да приступе заштићеним ресурсима и на крају смањујете ризик од потенцијалног нарушавања безбедности и губитка података.
Код овог пројекта можете пронаћи у њему ГитХуб репозиторијум.
Подесите Екпресс.јс Аполло сервер
Аполло Сервер је широко коришћена имплементација ГрапхКЛ сервера за ГрапхКЛ АПИ-је. Можете га користити да лако направите ГрапхКЛ шеме, дефинишете разрешиваче и управљате различитим изворима података за ваше АПИ-је.
Да бисте подесили Екпресс.јс Аполло сервер, креирајте и отворите фасциклу пројекта:
mkdir graphql-API-jwt
cd graphql-API-jwt
Затим покрените ову команду да бисте иницијализовали нови Ноде.јс пројекат користећи нпм, менаџер пакета Ноде:
npm init --yes
Сада инсталирајте ове пакете.
npm install apollo-server graphql mongoose jsonwebtokens dotenv
На крају, креирајте а сервер.јс датотеку у основном директоријуму и подесите свој сервер са овим кодом:
const { ApolloServer } = require('apollo-server');
const mongoose = require('mongoose');
require('dotenv').config();const typeDefs = require("./graphql/typeDefs");
const resolvers = require("./graphql/resolvers");const server = new ApolloServer({
typeDefs,
resolvers,
context: ({ req }) => ({ req }),
});const MONGO_URI = process.env.MONGO_URI;
mongoose
.connect(MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
console.log("Connected to DB");
return server.listen({ port: 5000 });
})
.then((res) => {
console.log(`Server running at ${res.url}`);
})
.catch(err => {
console.log(err.message);
});
ГрапхКЛ сервер је подешен са типеДефс и разрешивачи параметре, специфицирајући шему и операције којима АПИ може да рукује. Тхе контекст опција конфигурише рек објекат у контексту сваког разрешавача, што ће омогућити серверу да приступи детаљима специфичним за захтев као што су вредности заглавља.
Направите МонгоДБ базу података
Прво да бисте успоставили везу са базом података креирајте МонгоДБ базу података или поставите кластер на МонгоДБ Атлас. Затим копирајте наведени низ УРИ везе са базом података, креирајте а .енв датотеку и унесите низ везе на следећи начин:
MONGO_URI=""
Дефинишите модел података
Дефинишите модел података користећи Монгоосе. Створити нова модели/усер.јс датотеку и укључите следећи код:
const {model, Schema} = require('mongoose');
const userSchema = new Schema({
name: String,
password: String,
role: String
});
module.exports = model('user', userSchema);
Дефинишите ГрапхКЛ шему
У ГрапхКЛ АПИ-ју, шема дефинише структуру података који се могу испитивати, као и доступне операције (упити и мутације) које можете извршити за интеракцију са подацима путем АПИ.
Да бисте дефинисали шему, креирајте нову фасциклу у основном директоријуму вашег пројекта и дајте јој име грапхкл. Унутар ове фасцикле додајте две датотеке: типеДефс.јс и ресолверс.јс.
У типеДефс.јс датотеку, укључите следећи код:
const { gql } = require("apollo-server");
const typeDefs = gql`
type User {
id: ID!
name: String!
password: String!
role: String!
}
input UserInput {
name: String!
password: String!
role: String!
}
type TokenResult {
message: String
token: String
}
type Query {
users: [User]
}
type Mutation {
register(userInput: UserInput): User
login(name: String!, password: String!, role: String!): TokenResult
}
`;
module.exports = typeDefs;
Креирајте Ресолвере за ГрапхКЛ АПИ
Функције разрешивача одређују како се подаци преузимају као одговор на упите и мутације клијената, као и друга поља дефинисана у шеми. Када клијент пошаље упит или мутацију, ГрапхКЛ сервер покреће одговарајуће резолвере да обрађују и враћају потребне податке из различитих извора, као што су базе података или АПИ-ји.
Да бисте имплементирали аутентификацију и ауторизацију помоћу ЈСОН веб токена (ЈВТ), дефинишите разрешиваче за мутације регистра и пријављивања. Они ће управљати процесима регистрације и аутентификације корисника. Затим креирајте разрешивач упита за преузимање података који ће бити доступан само аутентификованим и овлашћеним корисницима.
Али прво, дефинишите функције за генерисање и верификацију ЈВТ-ова. У ресолверс.јс датотеку, почните додавањем следећих увоза.
const User = require("../models/user");
const jwt = require('jsonwebtoken');
const secretKey = process.env.SECRET_KEY;
Обавезно додајте тајни кључ који ћете користити за потписивање ЈСОН веб токена у .енв датотеку.
SECRET_KEY = '' ;
Да бисте генерисали токен за аутентификацију, укључите следећу функцију, која такође наводи јединствене атрибуте за ЈВТ токен, на пример, време истека. Поред тога, можете да уградите и друге атрибуте, као што су издати у одређено време, на основу ваших специфичних захтева апликације.
functiongenerateToken(user) {
const token = jwt.sign(
{ id: user.id, role: user.role },
secretKey,
{ expiresIn: '1h', algorithm: 'HS256' }
);
return token;
}
Сада имплементирајте логику верификације токена да бисте потврдили ЈВТ токене укључене у наредне ХТТП захтеве.
functionverifyToken(token) {
if (!token) {
thrownewError('Token not provided');
}
try {
const decoded = jwt.verify(token, secretKey, { algorithms: ['HS256'] });
return decoded;
} catch (err) {
thrownewError('Invalid token');
}
}
Ова функција ће узети токен као улаз, верификовати његову валидност помоћу наведеног тајног кључа и вратити декодирани токен ако је важећи, у супротном ће избацити грешку која указује на неважећи токен.
Дефинишите АПИ разрешиваче
Да бисте дефинисали разрешиваче за ГрапхКЛ АПИ, потребно је да наведете специфичне операције којима ће управљати, у овом случају, регистрацију корисника и операције пријављивања. Прво, креирајте а разрешивачи објекат који ће држати функције разрешивача, затим дефинишите следеће операције мутације:
const resolvers = {
Mutation: {
register: async (_, { userInput: { name, password, role } }) => {
if (!name || !password || !role) {
thrownewError('Name password, and role required');
}const newUser = new User({
name: name,
password: password,
role: role,
});try {
const response = await newUser.save();return {
id: response._id,
...response._doc,
};
} catch (error) {
console.error(error);
thrownewError('Failed to create user');
}
},
login: async (_, { name, password }) => {
try {
const user = await User.findOne({ name: name });if (!user) {
thrownewError('User not found');
}if (password !== user.password) {
thrownewError('Incorrect password');
}const token = generateToken(user);
if (!token) {
thrownewError('Failed to generate token');
}
return {
message: 'Login successful',
token: token,
};
} catch (error) {
console.error(error);
thrownewError('Login failed');
}
}
},
Тхе регистровати мутација управља процесом регистрације додавањем нових корисничких података у базу података. Док Пријавите се мутација управља пријављивањем корисника—по успешној аутентификацији, генерисаће ЈВТ токен, као и вратити поруку о успеху у одговору.
Сада укључите разрешивач упита за преузимање корисничких података. Да бисте осигурали да ће овај упит бити доступан само аутентификованим и овлашћеним корисницима, укључите логику ауторизације да бисте ограничили приступ само корисницима са Админ улога.
У суштини, упит ће прво проверити валидност токена, а затим и корисничку улогу. Ако је провера ауторизације успешна, упит разрешивача ће наставити да преузима и враћа податке корисника из базе података.
Query: {
users: async (parent, args, context) => {
try {
const token = context.req.headers.authorization || '';
const decodedToken = verifyToken(token);if (decodedToken.role !== 'Admin') {
thrownew ('Unauthorized. Only Admins can access this data.');
}
const users = await User.find({}, { name: 1, _id: 1, role:1 });
return users;
} catch (error) {
console.error(error);
thrownewError('Failed to fetch users');
}
},
},
};
Коначно, покрените развојни сервер:
node server.js
Сјајно! Сада, само напред и тестирајте функционалност АПИ-ја користећи Аполло Сервер АПИ сандбок у вашем претраживачу. На пример, можете користити регистровати мутацију за додавање нових корисничких података у базу података, а затим, Пријавите се мутација за аутентификацију корисника.
На крају, додајте ЈВТ токен у одељак заглавља ауторизације и наставите да тражите корисничке податке у бази података.
Обезбеђивање ГрапхКЛ АПИ-ја
Аутентификација и ауторизација су кључне компоненте за обезбеђивање ГрапхКЛ АПИ-ја. Ипак, важно је препознати да они сами по себи можда нису довољни да осигурају свеобухватну безбедност. Требало би да примените додатне безбедносне мере као што су провера ваљаности уноса и шифровање осетљивих података.
Усвајањем свеобухватног безбедносног приступа, можете заштитити своје АПИ-је од различитих потенцијалних напада.