Всем привет!
Пришел ответ с собеседования - не прошла. Вердикт: "есть пробелы в Spring Security, Spring JPA/Hibernate. Рекомендация: Изучить моменты Spring Security (Authentication, SecurityContext, Principal, GrantedAuthority). Так же подтянуть Hibernate."
Сразу стали вспоминаться вопросы именно по этим двум темам, на которые не ответила:
1. В чём разница между методом save у Hibernate и методом save у JpaRepository?
Вкратце, метод JpaRepository вызывает метод EntityManager.persist() - если сущность сохраняется впервые - либо метод EntityManager.merge() - если сущность обновляется. Метод save у Hibernate специфично ORM фреймворку и не работает со спецификацией JPA (вызывается метод Session.save, статья).
2. В чём разница между аутентификацией и авторизацией в Spring Security?
Аутентификация - процедура проверки подлинности (сравниваются введенный логин и пароль с сохраненным в базе данных)
Авторизация - предоставление прав на определенные действия (прав у админа, например, больше). (Статья)
3. Где хранится Authentication, как мы понимаем, что пользователь именно тот, за кого себя выдает?
Ответ: В SecurityContext. Две статьи на эту тему: раз и два.
Вот так разнятся требования на джунов, где-то спрашивают, зачем переопределять equals&hashCode, а где-то и такие вопросы задаются🤔
Пришел ответ с собеседования - не прошла. Вердикт: "есть пробелы в Spring Security, Spring JPA/Hibernate. Рекомендация: Изучить моменты Spring Security (Authentication, SecurityContext, Principal, GrantedAuthority). Так же подтянуть Hibernate."
Сразу стали вспоминаться вопросы именно по этим двум темам, на которые не ответила:
1. В чём разница между методом save у Hibernate и методом save у JpaRepository?
Вкратце, метод JpaRepository вызывает метод EntityManager.persist() - если сущность сохраняется впервые - либо метод EntityManager.merge() - если сущность обновляется. Метод save у Hibernate специфично ORM фреймворку и не работает со спецификацией JPA (вызывается метод Session.save, статья).
2. В чём разница между аутентификацией и авторизацией в Spring Security?
Аутентификация - процедура проверки подлинности (сравниваются введенный логин и пароль с сохраненным в базе данных)
Авторизация - предоставление прав на определенные действия (прав у админа, например, больше). (Статья)
3. Где хранится Authentication, как мы понимаем, что пользователь именно тот, за кого себя выдает?
Ответ: В SecurityContext. Две статьи на эту тему: раз и два.
Вот так разнятся требования на джунов, где-то спрашивают, зачем переопределять equals&hashCode, а где-то и такие вопросы задаются🤔
👍9
Всем привет!
Сегодня хочу порекомендовать курс со Stepik, называется «Middle Java Developer для МТС Банк». Он бесплатный, проводился для своих и, видимо, остался для остальных, кому интересно. Я вышла на него случайно, еще летом, но занималась по нему не активно. Даже периодически про него совсем забывая.
Вчера, когда сделала пару эндпоинтов для диплома, решила, что можно в честь выходного и отдохнуть от него и вспомнила про этот курс. Пошла читать, там у меня было открыто на Stream API, на моменте, где рассказывалось про метод GroupingBy у стримов. Он работает, как GROUP BY в SQL. В дипломе я его применила до этого, но больше случайно, погуглив. Но после статьи об этом методе с разными способами применения, очень понравились его возможности.
После стримов была ссылка на вебинар и мне очень понравился спикер. Он очень интересно рассказывал, давал интересные задачки на разные неоднозначные ситуации в многопоточности, потом приводил примеры из жизни, где такие ситуации происходят сплошь и рядом, если не учитывать некоторые моменты.
После этого оставшуюся часть дня смотрела другие вебинары с этого курса, благо на степике можно пропускать до любого интересного урока и заниматься, как удобно. Посмотрела вебинары этого спикера на тему Spring Security и интеграционного тестирования. Очень понравилось. В конце курса еще задание есть огромное, большой проект. Думаю сделаю его после диплома.
Диплом медленно идет, потому что заранее не знаешь как, что должно работать. Есть спецификация по эндпоинтам. Делаешь метод, тестируешь по их тестам Postman, оказывается, что в тестах вызывается другой, еще не написанный эндпоинт. Или по спецификации думаешь, что должен быть такой-то ответ, потом методом проб и ошибок в тестах постман, понимаешь, какой же ответ все-таки ожидается на самом деле.
Интереснее, когда есть идея сделать что-то и ты сидишь и думаешь как это сделать. Пишешь сама тесты, знаешь, что хочешь увидеть и видишь, когда что-то идет не так. Тут, наоборот, у тебя есть некоторые детали и ты из них собираешь общую картину, угадывая, как это должно взаимодействовать. Угадывая, потому что все тесты постман написаны со скрытыми деталями, типа {{request body}}, {{uid}}. То есть с одной стороны, test driven development, а с другой, guess driven development. Но делать нечего, надо его писать))
Сегодня хочу порекомендовать курс со Stepik, называется «Middle Java Developer для МТС Банк». Он бесплатный, проводился для своих и, видимо, остался для остальных, кому интересно. Я вышла на него случайно, еще летом, но занималась по нему не активно. Даже периодически про него совсем забывая.
Вчера, когда сделала пару эндпоинтов для диплома, решила, что можно в честь выходного и отдохнуть от него и вспомнила про этот курс. Пошла читать, там у меня было открыто на Stream API, на моменте, где рассказывалось про метод GroupingBy у стримов. Он работает, как GROUP BY в SQL. В дипломе я его применила до этого, но больше случайно, погуглив. Но после статьи об этом методе с разными способами применения, очень понравились его возможности.
После стримов была ссылка на вебинар и мне очень понравился спикер. Он очень интересно рассказывал, давал интересные задачки на разные неоднозначные ситуации в многопоточности, потом приводил примеры из жизни, где такие ситуации происходят сплошь и рядом, если не учитывать некоторые моменты.
После этого оставшуюся часть дня смотрела другие вебинары с этого курса, благо на степике можно пропускать до любого интересного урока и заниматься, как удобно. Посмотрела вебинары этого спикера на тему Spring Security и интеграционного тестирования. Очень понравилось. В конце курса еще задание есть огромное, большой проект. Думаю сделаю его после диплома.
Диплом медленно идет, потому что заранее не знаешь как, что должно работать. Есть спецификация по эндпоинтам. Делаешь метод, тестируешь по их тестам Postman, оказывается, что в тестах вызывается другой, еще не написанный эндпоинт. Или по спецификации думаешь, что должен быть такой-то ответ, потом методом проб и ошибок в тестах постман, понимаешь, какой же ответ все-таки ожидается на самом деле.
Интереснее, когда есть идея сделать что-то и ты сидишь и думаешь как это сделать. Пишешь сама тесты, знаешь, что хочешь увидеть и видишь, когда что-то идет не так. Тут, наоборот, у тебя есть некоторые детали и ты из них собираешь общую картину, угадывая, как это должно взаимодействовать. Угадывая, потому что все тесты постман написаны со скрытыми деталями, типа {{request body}}, {{uid}}. То есть с одной стороны, test driven development, а с другой, guess driven development. Но делать нечего, надо его писать))
🔥8👍2❤1
Всем привет!
Сегодняшний пост посвящается Spring Security.
Что такое Spring Security?
Его описывают, как мощный и хорошо настраиваемый фреймворк для контроля аутентификации и авторизации.
Spring Security - это фреймворк, который перехватывает запросы, аутентифицирует пользователей, применяет правила контроля доступа и защищает ваше приложение от угроз безопасности. Его главная цель убедиться, что ваше приложение защищенно, путем предоставления богатого набора инструментов для аутентификации и авторизации пользователей.
Как работает Spring Security?
Spring Security перехватывает HTTP запросы и пропускает через серию фильтров.
Сначала проверяет аутентифицирован ли пользователь (смотрит вошел ли пользователь, через свой логин/пароль), если нет, то перенаправляет его на страницу входа (для ввода логин/пароля).
Когда пользователь ввел данные, Spring Security сравнивает эти данные с теми, которые хранятся у нас в базе данных.
После аутентификации, Spring Security проверяет какие права и к каким ресурсам можно пустить пользователя (согласно нашей настройки).
Вот так может выглядеть метод, в котором мы прописываем фильтры для проверки пользовательских запросов (для версий Spring 3.0.9 и ниже):
Здесь пока можно увидеть, что для пути /admin будут допущены пользователи с ролью Admin, а к пути /users только пользователи с ролью User, также в этой цепочке фильтров можно увидеть, что к другим эндпоинтам разрешены любые запросы (anyRequest().permitAll()).
Определения взяты из Spring Security in Action by Laurentiu Spilca. Продолжение следует 🤓
Сегодняшний пост посвящается Spring Security.
Что такое Spring Security?
Его описывают, как мощный и хорошо настраиваемый фреймворк для контроля аутентификации и авторизации.
Spring Security - это фреймворк, который перехватывает запросы, аутентифицирует пользователей, применяет правила контроля доступа и защищает ваше приложение от угроз безопасности. Его главная цель убедиться, что ваше приложение защищенно, путем предоставления богатого набора инструментов для аутентификации и авторизации пользователей.
Как работает Spring Security?
Spring Security перехватывает HTTP запросы и пропускает через серию фильтров.
Сначала проверяет аутентифицирован ли пользователь (смотрит вошел ли пользователь, через свой логин/пароль), если нет, то перенаправляет его на страницу входа (для ввода логин/пароля).
Когда пользователь ввел данные, Spring Security сравнивает эти данные с теми, которые хранятся у нас в базе данных.
После аутентификации, Spring Security проверяет какие права и к каким ресурсам можно пустить пользователя (согласно нашей настройки).
Вот так может выглядеть метод, в котором мы прописываем фильтры для проверки пользовательских запросов (для версий Spring 3.0.9 и ниже):
@BeanПодробнее о том, что такое csrf и cors, а также, как изменилась настройка фильтров в более поздних версиях Spring, в следующих постах.
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.cors().disable()
.authorizeHttpRequests((authz) -> {
try {
authz
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/users/**").hasRole("USER")
.anyRequest().permitAll()
.and()
.exceptionHandling()
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
} catch (Exception e) {
throw new RuntimeException(e);
}
});
return http.build();
}
Здесь пока можно увидеть, что для пути /admin будут допущены пользователи с ролью Admin, а к пути /users только пользователи с ролью User, также в этой цепочке фильтров можно увидеть, что к другим эндпоинтам разрешены любые запросы (anyRequest().permitAll()).
Определения взяты из Spring Security in Action by Laurentiu Spilca. Продолжение следует 🤓
👍7🎄1
Привет!
Есть любители Ломбок? Делала на днях ревью (на интенсиве) и узнала новую для себя аннотацию- @Cleanup - заменяет try with resources. Очень украшает код.
Например, метод без аннотации:
Есть любители Ломбок? Делала на днях ревью (на интенсиве) и узнала новую для себя аннотацию- @Cleanup - заменяет try with resources. Очень украшает код.
Например, метод без аннотации:
public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream(args[0]);
try {
OutputStream out = new FileOutputStream(args[1]);
try {
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
} finally {
if (out != null) {
out.close();
}
}
} finally {
if (in != null) {
in.close();
}
}
}
А теперь метод с аннотацией:public static void main(String[] args) throws IOException {
@Cleanup InputStream in = new FileInputStream(args[0]);
@Cleanup OutputStream out = new FileOutputStream(args[1]);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
}
Мне понравилась идея 😊👍8🔥4
Всем привет!
Сегодня будет небольшой апдейт. На прошлой неделе немного выпала из жизни - писала диплом. Вчера отправила на проверку 2 этап. Когда зачтут, останется только добавить свою фичу небольшую и готово.
Думаю буду делать рейтинг событий с лайками, дизлайками и общей 5 звездочной оценкой. По заданию нужно будет самой написать Postman тесты - это будет новый опыт для меня. До этого тестировала там сама свои проекты вручную, проверяя разные запросы на разные эндпоинты, потом уже писала юнит и интеграционные тесты.
Стала потихоньку возвращаться к книжкам, курсу на степике. Сейчас у меня одновременно начато очень много книг, поэтому решила читать по очереди, чтобы не разрываться. Первая в очереди Spring Security in Action, очень стала интересна тема безопасности, столько в ней есть нюансов, что хочется в этом разбираться.
Потом думаю буду дочитывать Kafka в действии и Spring Паттерны. Сегодня попалось в каком-то чате, что есть Kafka Security (streams security) - захотелось посмотреть, почитать.
Но всё сразу читать не получается, буду стараться сохранять очередность))
Сегодня будет небольшой апдейт. На прошлой неделе немного выпала из жизни - писала диплом. Вчера отправила на проверку 2 этап. Когда зачтут, останется только добавить свою фичу небольшую и готово.
Думаю буду делать рейтинг событий с лайками, дизлайками и общей 5 звездочной оценкой. По заданию нужно будет самой написать Postman тесты - это будет новый опыт для меня. До этого тестировала там сама свои проекты вручную, проверяя разные запросы на разные эндпоинты, потом уже писала юнит и интеграционные тесты.
Стала потихоньку возвращаться к книжкам, курсу на степике. Сейчас у меня одновременно начато очень много книг, поэтому решила читать по очереди, чтобы не разрываться. Первая в очереди Spring Security in Action, очень стала интересна тема безопасности, столько в ней есть нюансов, что хочется в этом разбираться.
Потом думаю буду дочитывать Kafka в действии и Spring Паттерны. Сегодня попалось в каком-то чате, что есть Kafka Security (streams security) - захотелось посмотреть, почитать.
Но всё сразу читать не получается, буду стараться сохранять очередность))
🔥7👍2
Всем привет!
На днях в Практикуме был вебинар с нашим наставником группы. Его спросили про JPA и Null параметры. Он предложил вариант сделать дерево условий, если этот пришедший параметр null, то не передавать его в метод репозитория.
Самое интересное, что в нашем случае приходило 7 null параметров в одном из тестов. Кажется, что это 7 условий. Но что если приходит 5 параметров null, а остальные не null? Это дополнительное условие, потому что нет колонок со значением null в нашей таблице событий. Когда я делала этот эндпоинт, я прикинула, что это (минимум) 21 вариация. 14 if-else условий проверки на null на каждый параметр, плюс варианты, когда первые два null, а остальные не null, первый и третий null, а остальные не null. В этом духе.
Естественно, этот момент предусмотрен в Spring Data JPA. Подробнее можно посмотреть в этой статье. Я выпишу пример с коротким объяснением из этой статьи:
Может кому пригодится, если вдруг кто не знал про это.
На днях в Практикуме был вебинар с нашим наставником группы. Его спросили про JPA и Null параметры. Он предложил вариант сделать дерево условий, если этот пришедший параметр null, то не передавать его в метод репозитория.
Самое интересное, что в нашем случае приходило 7 null параметров в одном из тестов. Кажется, что это 7 условий. Но что если приходит 5 параметров null, а остальные не null? Это дополнительное условие, потому что нет колонок со значением null в нашей таблице событий. Когда я делала этот эндпоинт, я прикинула, что это (минимум) 21 вариация. 14 if-else условий проверки на null на каждый параметр, плюс варианты, когда первые два null, а остальные не null, первый и третий null, а остальные не null. В этом духе.
Естественно, этот момент предусмотрен в Spring Data JPA. Подробнее можно посмотреть в этой статье. Я выпишу пример с коротким объяснением из этой статьи:
@Query("SELECT c FROM Customer c WHERE (:name is null or c.name = :name) and (:email is null or c.email = :email)")
List<Customer> findCustomerByNameAndEmail(@Param("name") String name, @Param("email") String email);
В этом случае, если параметр name будет null, условие будет верно всегда и не повлияет на выборку WHERE. По поводу конструкции @Param("name"), в моем случае работало и без нее. Может кому пригодится, если вдруг кто не знал про это.
Baeldung on Kotlin
Spring Data JPA and Null Parameters | Baeldung
Learn different ways to use null parameters with Spring Data JPA queries, including how to make query parameters optional.
👍11🔥1
Всем привет!
C 19 сентября из каждого (утюга) java канала сообщалось про выход новой версии java 21. А мой канал что? Не утюг? 😅 На самом деле, расписывать новшества я не буду, потому что они уже много где были хорошо описаны, например, я читала, кроме документации, эту статью.
Диплом мне сегодня зачли, поэтому самое время начать вплотную знакомиться с новой версией джава. Меня привлекло, что в новой версии в switch кейсах, наконец, можно будет добавлять условие, с помощью ключевого слова when:
Я такую возможность захотела в первый день, когда впервые экспериментировала со switch конструкцией в прошлом году. Единственное, смущает, что новый паттерн-матчинг имеет ограничения, например, что кейсы должны быть исчерпывающими. Но в этом плане я еще не до конца разобралась, сегодня только пришла идея поэкспериментировать с нововведениями.
Еще из новостей, во вторник у меня было собеседование на стажировку в нашем городе. Результаты будут только на следующей неделе. Вопросы были очень легкими, в стиле, что такое класс Object, какие у него есть методы? Чем отличается ArrayList от LinkedList? Как, вкратце, устроена HashMap? Чем отличается аннотация @Controller от @RestController? Зачем ставить аннотацию @Repository? Такого рода вопросы.
C 19 сентября из каждого (
Диплом мне сегодня зачли, поэтому самое время начать вплотную знакомиться с новой версией джава. Меня привлекло, что в новой версии в switch кейсах, наконец, можно будет добавлять условие, с помощью ключевого слова when:
case Integer i when i > 0 -> String.format("positive int %d", i); Я такую возможность захотела в первый день, когда впервые экспериментировала со switch конструкцией в прошлом году. Единственное, смущает, что новый паттерн-матчинг имеет ограничения, например, что кейсы должны быть исчерпывающими. Но в этом плане я еще не до конца разобралась, сегодня только пришла идея поэкспериментировать с нововведениями.
Еще из новостей, во вторник у меня было собеседование на стажировку в нашем городе. Результаты будут только на следующей неделе. Вопросы были очень легкими, в стиле, что такое класс Object, какие у него есть методы? Чем отличается ArrayList от LinkedList? Как, вкратце, устроена HashMap? Чем отличается аннотация @Controller от @RestController? Зачем ставить аннотацию @Repository? Такого рода вопросы.
Teletype
Вышла Java 21
Вышла общедоступная версия Java 21. В этот релиз попало около 2500 закрытых задач и 15 JEP\'ов. Release Notes можно посмотреть здесь...
🔥5😁2
Самое главное, ради чего писался пост, забыла написать 😁:
Презентацию новой версии я частично смотрела онлайн. Приободрило, как начинающего разработчика, когда у троих опытных разработчиков Oracle не получилось запустить видео со звуком. Минут 5 они возились и говорили разные приободряющие слова, в стиле: «Мы разработчики, нам свойственно ошибаться. Но мы не сдаемся, пока не победим»💪
Презентацию новой версии я частично смотрела онлайн. Приободрило, как начинающего разработчика, когда у троих опытных разработчиков Oracle не получилось запустить видео со звуком. Минут 5 они возились и говорили разные приободряющие слова, в стиле: «Мы разработчики, нам свойственно ошибаться. Но мы не сдаемся, пока не победим»💪
😁8
Всем привет!
Хочу рассказать о том, что поняла только на днях (к своему стыду). Первый звонок, что что-то здесь не так, прозвучал, когда писала пост про null параметры. Сначала я написала, что это JPA Hibernate, потом перечитала начало статьи и увидела, что это Spring Data JPA, исправила.
Потом посмотрела видео про паттерны в Spring, Евгения Борисова, услышала ещё раз про Spring Data, второй звонок.
Вчера начала читать книгу про Hibernate (идея с чтением книг последовательно, окончательно провалилась) и паззл в голове сложился.
Есть 3 отдельных понятия: JPA, Native Hibernate, Spring Data JPA.
Как я думала до этого? Что есть спецификация JPA со стандартами, есть ORM фреймворк для выполнения этих стандартов, один из таких Hibernate. И есть где-то Spring Data, которая что-то где-то делает, где и что я не знала.
Так вот оказывается Spring Data JPA делала много чего у меня прямо под носом: делала реализацию моих запросных методов (findByNameAndEmail), бин-реализацию для моих интерфейсов-репозиториев, которые наследовались от JpaRepository, и избавляла меня от написания повторяющегося кода.
Сейчас я точно вспоминаю, что нам про это рассказывалось в теории в Практикуме, но в тот момент в голове по полкам не разложилось. Лучше поздно, чем никогда 😅
Хочу рассказать о том, что поняла только на днях (к своему стыду). Первый звонок, что что-то здесь не так, прозвучал, когда писала пост про null параметры. Сначала я написала, что это JPA Hibernate, потом перечитала начало статьи и увидела, что это Spring Data JPA, исправила.
Потом посмотрела видео про паттерны в Spring, Евгения Борисова, услышала ещё раз про Spring Data, второй звонок.
Вчера начала читать книгу про Hibernate (идея с чтением книг последовательно, окончательно провалилась) и паззл в голове сложился.
Есть 3 отдельных понятия: JPA, Native Hibernate, Spring Data JPA.
Как я думала до этого? Что есть спецификация JPA со стандартами, есть ORM фреймворк для выполнения этих стандартов, один из таких Hibernate. И есть где-то Spring Data, которая что-то где-то делает, где и что я не знала.
Так вот оказывается Spring Data JPA делала много чего у меня прямо под носом: делала реализацию моих запросных методов (findByNameAndEmail), бин-реализацию для моих интерфейсов-репозиториев, которые наследовались от JpaRepository, и избавляла меня от написания повторяющегося кода.
Сейчас я точно вспоминаю, что нам про это рассказывалось в теории в Практикуме, но в тот момент в голове по полкам не разложилось. Лучше поздно, чем никогда 😅
👍5🔥1
Всем привет!
Есть ли жизнь после Практикума?🤪 Когда долго ждешь окончания чего-нибудь, и это на самом деле заканчивается, становится немного пусто, появляются мысли: "И что теперь?"
В пятницу я неофициально закончила курсы "Java-разработчика" в Яндекс.Практикум (официальное окончание будет 14 октября). Получается надо редактировать свой вступительный пост здесь.🤭 Но глобально, что же делать дальше?
Когда была система спринтов и я раньше времени что-то заканчивала, четко знала, что будет дальше в программе (в общих чертах), знала что всегда будет какой-то проект, задачки/тесты. А тут появилась неуверенность в "завтрашней программе".
Поэтому пошла искать себе такую программу. Посмотрела разные пути развития (roadmap), требования из нескольких вакансий, и наметила себе посмотреть Elasticsearch, GraphQL, MongoDB и, возможно, Kubernetes.
Нашла классный туториал по первому здесь, по второму здесь, а по MongoDB недавно скачала классную книжку (MongoDb for Jobseekers).
Также ещё нашла интересный репозиторий на гитхаб с полезными ссылками, awesome java, и там нашла интересную вещь, как game development engines для разработки игр на java. Я давно сыну обещала сделать игру для него в стиле его любимой игры, думаю попробовать jMonkeyEngine.
Посчитала, из относительно крупных учебных проектов у меня накопилось 4 учебных, и 4 своих (2 из них появились благодаря интересным тестовым заданиям). Был у меня репозиторий сфоркнутый с тестовыми заданиями, думала взять какую-нибудь идею в разработку, но в основном проекты там мелкие, в стиле "простой калькулятор", игра, где смысл показать, что ты умеешь в наследование.
Поэтому отфоркнула этот репозиторий, добавила в свой блог-проект создание постов с ролью авторов (method security), и, отложив его пока, решила разнообразить свое портфолио ещё и игрой на java. В блог можно, конечно, добавить рейтинг, комментарии, но это всё выглядит в принципе не очень сложно, несколько раз реализовывала похожий и такой же функционал и совсем недавно, поэтому решила пока переключиться и попробовать сделать что-то совсем другое (дополнительно к туториалам выше).👨💻
Есть ли жизнь после Практикума?🤪 Когда долго ждешь окончания чего-нибудь, и это на самом деле заканчивается, становится немного пусто, появляются мысли: "И что теперь?"
В пятницу я неофициально закончила курсы "Java-разработчика" в Яндекс.Практикум (официальное окончание будет 14 октября). Получается надо редактировать свой вступительный пост здесь.🤭 Но глобально, что же делать дальше?
Когда была система спринтов и я раньше времени что-то заканчивала, четко знала, что будет дальше в программе (в общих чертах), знала что всегда будет какой-то проект, задачки/тесты. А тут появилась неуверенность в "завтрашней программе".
Поэтому пошла искать себе такую программу. Посмотрела разные пути развития (roadmap), требования из нескольких вакансий, и наметила себе посмотреть Elasticsearch, GraphQL, MongoDB и, возможно, Kubernetes.
Нашла классный туториал по первому здесь, по второму здесь, а по MongoDB недавно скачала классную книжку (MongoDb for Jobseekers).
Также ещё нашла интересный репозиторий на гитхаб с полезными ссылками, awesome java, и там нашла интересную вещь, как game development engines для разработки игр на java. Я давно сыну обещала сделать игру для него в стиле его любимой игры, думаю попробовать jMonkeyEngine.
Посчитала, из относительно крупных учебных проектов у меня накопилось 4 учебных, и 4 своих (2 из них появились благодаря интересным тестовым заданиям). Был у меня репозиторий сфоркнутый с тестовыми заданиями, думала взять какую-нибудь идею в разработку, но в основном проекты там мелкие, в стиле "простой калькулятор", игра, где смысл показать, что ты умеешь в наследование.
Поэтому отфоркнула этот репозиторий, добавила в свой блог-проект создание постов с ролью авторов (method security), и, отложив его пока, решила разнообразить свое портфолио ещё и игрой на java. В блог можно, конечно, добавить рейтинг, комментарии, но это всё выглядит в принципе не очень сложно, несколько раз реализовывала похожий и такой же функционал и совсем недавно, поэтому решила пока переключиться и попробовать сделать что-то совсем другое (дополнительно к туториалам выше).👨💻
👍8❤1
Всем привет!
Я прошла на стажировку! Точнее, я прошла на две стажировки, но одна из них была в Астон, где очень жесткие условия. Поэтому туда я отказалась идти. На прошлой неделе у меня было собеседование на другую стажировку с возможностью дальнейшего трудоустройства в их компанию. Вчера пришел результат, что я прошла, начало будет 2 октября. Поделюсь впечатлениями, как начнется.
Вчера еще вспомнила про курс для миддлов со степика. Еще раз захотелось его порекомендовать, он бесплатный. Там многие вещи пересекаются с курса Я.Практикума для джунов, но чем мне нравится — деталями по темам. Курс, видимо, создан был Семеном Кирековым, потому что его вебинары на курсе самые крутые и полезные и ссылки на «почитать подробнее на тему» ведут на его блог. Правда, пишет он там на английском, поэтому подойдет не всем. Но на степике теоретические статьи на русском.
На моем собеседовании по Spring и Hibernate, собеседующий спросил меня, как правильно создавать базы для приложения. Я наивно ответила, что нужно создавать файл schema.sql. Он сказал: «Нет, есть способ лучше». Но какой не сказал. Тут на курсе, нашла ответ — нужно делать, так называемые, миграции. В курсе рассказывается про инструмент миграции Liquibase, приведены примеры как, объяснено почему.
Еще интересная вещь, которую я сегодня там прочитала — объяснение, что это за такое предупреждение, которое у нас всегда выходило в учебных проектах, помню даже ответ наставника, мол, не заморачивайтесь. Вот так выглядит это предупреждение:
«Суть данного антипаттерна в том, что сессия Hibernate открывается и закрывается не в сервисном слое, а в слое "выше" - на уровне представления (view layer), к примеру в контроллере. Контроллер вызывает сервисный слой, который выполняет различные действия с данными и возвращает управление контроллеру. А поскольку сессия всё ещё открыта, слой представления может инициализировать объекты, для которых указана "ленивая" загрузка. Однако если сервисный слой выполнит commit, то транзакция завершится. Из-за этого Hibernate будет выполнять все SQL-запросы, инициированные на слое представления, в режиме auto-commit, то есть каждый такой SQL-запрос будет выполняться в отдельной транзакции, что приведёт к повышению нагрузки на БД, т.к. в конце каждой транзакции БД должна сделать запись в журнале транзакций на диске, что является ресурсозатратной операцией.
Помимо повышения нагрузки на БД у Open Session In View есть и другой недостаток. Поскольку операции выполняются не в одной транзакции, а в двух и более, можно получить неконсистентное состояние данных. Spring Boot по умолчанию использует Open Session in View.» Чтобы это отключить, нужно установить false параметру spring.jpa.open-in-view в application.properties.
Я прошла на стажировку! Точнее, я прошла на две стажировки, но одна из них была в Астон, где очень жесткие условия. Поэтому туда я отказалась идти. На прошлой неделе у меня было собеседование на другую стажировку с возможностью дальнейшего трудоустройства в их компанию. Вчера пришел результат, что я прошла, начало будет 2 октября. Поделюсь впечатлениями, как начнется.
Вчера еще вспомнила про курс для миддлов со степика. Еще раз захотелось его порекомендовать, он бесплатный. Там многие вещи пересекаются с курса Я.Практикума для джунов, но чем мне нравится — деталями по темам. Курс, видимо, создан был Семеном Кирековым, потому что его вебинары на курсе самые крутые и полезные и ссылки на «почитать подробнее на тему» ведут на его блог. Правда, пишет он там на английском, поэтому подойдет не всем. Но на степике теоретические статьи на русском.
На моем собеседовании по Spring и Hibernate, собеседующий спросил меня, как правильно создавать базы для приложения. Я наивно ответила, что нужно создавать файл schema.sql. Он сказал: «Нет, есть способ лучше». Но какой не сказал. Тут на курсе, нашла ответ — нужно делать, так называемые, миграции. В курсе рассказывается про инструмент миграции Liquibase, приведены примеры как, объяснено почему.
Еще интересная вещь, которую я сегодня там прочитала — объяснение, что это за такое предупреждение, которое у нас всегда выходило в учебных проектах, помню даже ответ наставника, мол, не заморачивайтесь. Вот так выглядит это предупреждение:
2022-04-13 23:01:34.863 WARN 109326 --- [main] JpaBaseConfiguration$JpaWebConfiguration :Оказывается, это антипаттерн с названием Open Session in View. Он сделан для обхода исключения LazyInitializationException, которое бросает Hibernate, когда ему необходимо инициализировать связанную сущность, для которой указана «ленивая» загрузка, но при этом отсутствует контекст сессии Hibernate (попросту говоря, когда мы запросили сущность из базы без дополнительных полей — сущностей хранящихся в других таблицах, а потом обратились к этим полям, по типу event.getCategories() или book.getGenres()).
spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering.
Explicitly configure spring.jpa.open-in-view to disable this warning
«Суть данного антипаттерна в том, что сессия Hibernate открывается и закрывается не в сервисном слое, а в слое "выше" - на уровне представления (view layer), к примеру в контроллере. Контроллер вызывает сервисный слой, который выполняет различные действия с данными и возвращает управление контроллеру. А поскольку сессия всё ещё открыта, слой представления может инициализировать объекты, для которых указана "ленивая" загрузка. Однако если сервисный слой выполнит commit, то транзакция завершится. Из-за этого Hibernate будет выполнять все SQL-запросы, инициированные на слое представления, в режиме auto-commit, то есть каждый такой SQL-запрос будет выполняться в отдельной транзакции, что приведёт к повышению нагрузки на БД, т.к. в конце каждой транзакции БД должна сделать запись в журнале транзакций на диске, что является ресурсозатратной операцией.
Помимо повышения нагрузки на БД у Open Session In View есть и другой недостаток. Поскольку операции выполняются не в одной транзакции, а в двух и более, можно получить неконсистентное состояние данных. Spring Boot по умолчанию использует Open Session in View.» Чтобы это отключить, нужно установить false параметру spring.jpa.open-in-view в application.properties.
Stepik: online education
Middle Java Developer для МТС Банк
Курс для подготовки Middle Java Developer
❤6🔥6👏4👍1
Всем привет!
Хочу рассказать об интересной вещи, которую узнала вчера-позавчера. Начну немного издалека. Не очень давно, на последнем моем занятии на интенсиве, мы обсуждали Hibernate и кто-то задал вопрос: "почему считается, что 'жадная' выборка данных (fetch eager) не решает проблему n + 1? Казалось бы, не для этого ли ее придумали?"
Вкратце напомню, что это за проблема "n + 1". Она часто возникает, когда мы обращаемся к какой-то сущности, например, книге, которая имеет связь с другой сущностью, например, жанром. У одной книги может быть несколько жанров, и у одного жанра может быть несколько книг. Такая связь называется многие-ко-многим и по умолчанию в Hibernate для нее выполняется ленивая загрузка (fetch lazy).
Таким образом, если мы запросим список книг из репозитория, Hibernate сгенерирует один запрос. Если мы захотим пройтись по жанрам книг в цикле, в каких-нибудь статистических, фильтрующих или других целях, из-за того, что загрузка жанров ленивая, то есть данные запрашиваются только тогда, когда они нужны, для каждой книги Hibernate сделает дополнительный запрос в базу данных, чтобы получить жанры этой книги.
Что делает Hibernate, если указать параметр fetch EAGER? Он генерирует дополнительные запросы сразу, до обращения к жанрам, поэтому EAGER не решает проблемы n + 1!
Это я узнала буквально пару дней назад и это меня очень поразило🤓
P. S. Это не решение проблемы n + 1, это объяснение почему FETCH EAGER не решает эту проблему. О решениях будет отдельный пост позже 🤗
Хочу рассказать об интересной вещи, которую узнала вчера-позавчера. Начну немного издалека. Не очень давно, на последнем моем занятии на интенсиве, мы обсуждали Hibernate и кто-то задал вопрос: "почему считается, что 'жадная' выборка данных (fetch eager) не решает проблему n + 1? Казалось бы, не для этого ли ее придумали?"
Вкратце напомню, что это за проблема "n + 1". Она часто возникает, когда мы обращаемся к какой-то сущности, например, книге, которая имеет связь с другой сущностью, например, жанром. У одной книги может быть несколько жанров, и у одного жанра может быть несколько книг. Такая связь называется многие-ко-многим и по умолчанию в Hibernate для нее выполняется ленивая загрузка (fetch lazy).
Таким образом, если мы запросим список книг из репозитория, Hibernate сгенерирует один запрос. Если мы захотим пройтись по жанрам книг в цикле, в каких-нибудь статистических, фильтрующих или других целях, из-за того, что загрузка жанров ленивая, то есть данные запрашиваются только тогда, когда они нужны, для каждой книги Hibernate сделает дополнительный запрос в базу данных, чтобы получить жанры этой книги.
List<Book> books = bookRepository.findAll();
for (Book book : books) {
List<Genre> genres = book.getGenres();
// делаем что-то с жанрами
}
Что делает Hibernate, если указать параметр fetch EAGER? Он генерирует дополнительные запросы сразу, до обращения к жанрам, поэтому EAGER не решает проблемы n + 1!
Это я узнала буквально пару дней назад и это меня очень поразило🤓
P. S. Это не решение проблемы n + 1, это объяснение почему FETCH EAGER не решает эту проблему. О решениях будет отдельный пост позже 🤗
👍10❤1
Всем привет!
Вчера у меня началась классная стажировка. Было первое занятие, познакомились, наметили план работы. Впечатления отличные.
Будем разрабатывать интересный проект. Он будет включать в себя 6 микросервисов (плюс минус). В проекте будет использоваться Liquibase, Spring Security, RabbitMQ (возможно аналог), будут push-уведомления, обращения к внешним сервисам. В общем, очень близко к настоящему взрослому проекту. Будут допущены некоторые упрощения в учебных целях, но для меня это будет самый большой проект, пока что.
Liquibase, кстати, начала тестировать в выходные. Решила сделать проект из курса для миддлов (до этого планировала переключиться на разработку игры на jMonkeyEngine и что-то пока ничего из этого не вышло, даже не знаю с чего там начать).
С Liquibase не сразу получилось, я ещё включила у Hibernate настройку для ddl-auto на validate, по совету с курса, чтобы была проверка на соответствие сущностей и реальной базы. Учитывая, что первый раз делала базы через Liquibase, проект у меня очень долго не заводился, но было интересно. В конце концов получилось, думаю в свободное время буду продолжать его делать, пока не началась активная разработка нового проекта.
Вчера у меня началась классная стажировка. Было первое занятие, познакомились, наметили план работы. Впечатления отличные.
Будем разрабатывать интересный проект. Он будет включать в себя 6 микросервисов (плюс минус). В проекте будет использоваться Liquibase, Spring Security, RabbitMQ (возможно аналог), будут push-уведомления, обращения к внешним сервисам. В общем, очень близко к настоящему взрослому проекту. Будут допущены некоторые упрощения в учебных целях, но для меня это будет самый большой проект, пока что.
Liquibase, кстати, начала тестировать в выходные. Решила сделать проект из курса для миддлов (до этого планировала переключиться на разработку игры на jMonkeyEngine и что-то пока ничего из этого не вышло, даже не знаю с чего там начать).
С Liquibase не сразу получилось, я ещё включила у Hibernate настройку для ddl-auto на validate, по совету с курса, чтобы была проверка на соответствие сущностей и реальной базы. Учитывая, что первый раз делала базы через Liquibase, проект у меня очень долго не заводился, но было интересно. В конце концов получилось, думаю в свободное время буду продолжать его делать, пока не началась активная разработка нового проекта.
👍8👏2
Всем привет!
Смотрела вчера лекцию по API безопасности. Там говорилось о последних стандартах PCI DSS 4.0*, которые должны применить у себя компании до 1 квартала 2024 года.
Вкратце расскажу несколько моментов, что было сказано в видео:
1. Количество API растёт, в прогнозах ещё больше будет рост, в силу удобства подхода.
2. Часто делают проверки безопасности на уровне клиента (браузера, например) - делают невидимыми различные кнопки пользователям без доступа к таким ресурсам, к примеру. В этом случае злоумышленники, если найдут верный эндпоинт, могут напрямую получить доступ к данным (отправив прямой запрос на эндпоинт), если нет дополнительных проверок для API.
3. Одной из хороших практик была названа практика Security Gateway, специальный сервис, ответственность которого аутентифицировать и авторизовывать пользователей.
Сразу же загорелась попробовать реализовать такой сервис в последнем проекте с миддл курса. Если следовать их ТЗ, там тоже есть упрощения, которые я хочу усложнить для себя и попробовать сделать ближе к тому, как надо. Поэтому этот проект превращается в мой пет, потому что я меняю для себя требования, как должно работать. Тем более, что начала писать на хайпе на Java 21 (может я увидела хайп там, где его нет, конечно 😅) и на последней стабильной версии Spring Boot. Там настройка Spring Security немного отличается.
Осталось дело за малым, найти как это правильно сделать 😅, нашла пока статью с 7 вариантами, буду что-нибудь из этого пробовать)
P. S. Кстати, не говорила вроде бы, что этот проект - клон учебного сайта Coursera (на минималках).
*Стандарт PCI DSS — это международный стандарт безопасности, созданный специально для защиты данных платежных карт.
Смотрела вчера лекцию по API безопасности. Там говорилось о последних стандартах PCI DSS 4.0*, которые должны применить у себя компании до 1 квартала 2024 года.
Вкратце расскажу несколько моментов, что было сказано в видео:
1. Количество API растёт, в прогнозах ещё больше будет рост, в силу удобства подхода.
2. Часто делают проверки безопасности на уровне клиента (браузера, например) - делают невидимыми различные кнопки пользователям без доступа к таким ресурсам, к примеру. В этом случае злоумышленники, если найдут верный эндпоинт, могут напрямую получить доступ к данным (отправив прямой запрос на эндпоинт), если нет дополнительных проверок для API.
3. Одной из хороших практик была названа практика Security Gateway, специальный сервис, ответственность которого аутентифицировать и авторизовывать пользователей.
Сразу же загорелась попробовать реализовать такой сервис в последнем проекте с миддл курса. Если следовать их ТЗ, там тоже есть упрощения, которые я хочу усложнить для себя и попробовать сделать ближе к тому, как надо. Поэтому этот проект превращается в мой пет, потому что я меняю для себя требования, как должно работать. Тем более, что начала писать на хайпе на Java 21 (может я увидела хайп там, где его нет, конечно 😅) и на последней стабильной версии Spring Boot. Там настройка Spring Security немного отличается.
Осталось дело за малым, найти как это правильно сделать 😅, нашла пока статью с 7 вариантами, буду что-нибудь из этого пробовать)
P. S. Кстати, не говорила вроде бы, что этот проект - клон учебного сайта Coursera (на минималках).
*Стандарт PCI DSS — это международный стандарт безопасности, созданный специально для защиты данных платежных карт.
YouTube
API Security for PCI Compliance (Data Security Standard)
Learn about API security with this course that is tailored to address the pivotal PCI DSS 4.0 requirements. PCI DSS stands for Payment Card Industry Data Security Standard. It is a set of security standards designed to ensure that all companies that accept…
👍8❤1
Всем привет!
Вернемся к проблеме “n + 1”, о которой я недавно делала пост. Там я рассказала об одном соблазнительном, но неправильном решении. Кстати сказать, один раз я применила его летом в одном из ТЗ Я.Практикума. Тогда мне ревьюер интересно ответила, что раньше бы она сказала на fetch eager, что это 100% нельзя использовать, но сейчас у них тимлид заставляет всех использовать fetch eager на проекте. То есть можно представить, какая нагрузка идет на базу данных, когда ВСЕ запросы идут, как n + 1, правда?
Какие есть правильные решения?
1. Использовать JOIN FETCH в аннотации @Query:
Хочу сказать интересную вещь про join fetch.
Возможно это для всех сразу стало очевидным, когда они первый раз прочитали про join fetch, но я об этом узнала только вчера. Оказывается join fetch — это inner join fetch, то есть если нам нужно соединение left join, то нужно указывать left join fetch. Я этого не знала, на дипломе в таких случаях использовала запросы на нативном SQL в @Query. Об @EntityGraph я также не знала еще неделю-две назад, ее еще не применяла на практике. Но в этой статье можно посмотреть примеры, как ее нужно применять.
Вернемся к проблеме “n + 1”, о которой я недавно делала пост. Там я рассказала об одном соблазнительном, но неправильном решении. Кстати сказать, один раз я применила его летом в одном из ТЗ Я.Практикума. Тогда мне ревьюер интересно ответила, что раньше бы она сказала на fetch eager, что это 100% нельзя использовать, но сейчас у них тимлид заставляет всех использовать fetch eager на проекте. То есть можно представить, какая нагрузка идет на базу данных, когда ВСЕ запросы идут, как n + 1, правда?
Какие есть правильные решения?
1. Использовать JOIN FETCH в аннотации @Query:
@Query(value = "" +2. Использовать аннотацию @EntityGraph над методом в репозитории:
"SELECT c FROM Course c " +
" JOIN FETCH c.lessons")
List<Course> findAll();
@EntityGraph(attributePaths = {"lessons"})
List<Course> findAllUsingEntityGraph();
В аргументе attributePaths аннотации @EntityGraph указывается тот объект, который необходимо инициализировать сразу, несмотря на установленный у него ленивый тип загрузки.Хочу сказать интересную вещь про join fetch.
Возможно это для всех сразу стало очевидным, когда они первый раз прочитали про join fetch, но я об этом узнала только вчера. Оказывается join fetch — это inner join fetch, то есть если нам нужно соединение left join, то нужно указывать left join fetch. Я этого не знала, на дипломе в таких случаях использовала запросы на нативном SQL в @Query. Об @EntityGraph я также не знала еще неделю-две назад, ее еще не применяла на практике. Но в этой статье можно посмотреть примеры, как ее нужно применять.
👍3🔥2
Всем привет!
Хочу сегодня поделиться интересным видео по дебагу. Это было для меня последнее видео из курса со степика, на этом теоретическую часть я закончила, останется только дописать проект.
Тема видео кажется несложной, всем известной. Я сама сначала сомневалась, стоит ли его смотреть, подумав, что про дебаг я знаю много, сколько багов отловила у себя в программах, даже несколько раз отлавливала баги в чужом коде. Но все-таки решила посмотреть, чтобы закончить с теорией и перейти к оставшейся части.
Не пожалела, узнала много новых фишек, поняла, что есть ещё больше, о чем не рассказали в видео. Поэтому решила посоветовать его здесь, может кому-нибудь пригодится 😊
А я пока вернусь к Spring Security in Action, осталось до конца совсем немного, потом буду смотреть в документации замены для устаревших методов (на выходных научилась это искать там) и буду дописывать свою курсэру (тру-сэру? или, может, трус-курс? 🤣).
Хочу сегодня поделиться интересным видео по дебагу. Это было для меня последнее видео из курса со степика, на этом теоретическую часть я закончила, останется только дописать проект.
Тема видео кажется несложной, всем известной. Я сама сначала сомневалась, стоит ли его смотреть, подумав, что про дебаг я знаю много, сколько багов отловила у себя в программах, даже несколько раз отлавливала баги в чужом коде. Но все-таки решила посмотреть, чтобы закончить с теорией и перейти к оставшейся части.
Не пожалела, узнала много новых фишек, поняла, что есть ещё больше, о чем не рассказали в видео. Поэтому решила посоветовать его здесь, может кому-нибудь пригодится 😊
А я пока вернусь к Spring Security in Action, осталось до конца совсем немного, потом буду смотреть в документации замены для устаревших методов (на выходных научилась это искать там) и буду дописывать свою курсэру (тру-сэру? или, может, трус-курс? 🤣).
YouTube
Летняя школа 2021 - Бэкенд разработка, воркшоп 6
Запись воркшопа - "Debug". Ментор - Денис Тимофеев.
05.08.2021
05.08.2021
🔥6😁2👍1
Всем привет!
Как-то писала, что реализовывала Spring Security с дополнительным фильтром на JWT, но не написала, что такое JWT.
Хочу сегодня это исправить 👨💻 Для тех, кто не знает, надеюсь будет интересно, а кто знает, надеюсь, поправит меня, если я где-то ошибусь 😊
Итак, как вообще расшифровывается JWT? Расшифровывается, как JSON Web Token.
Как он выглядит?
Примерно, вот так (новые строчки добавлены для удобства чтения):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
Это своего рода закодированное сообщение. По условному разделению по строкам, верхняя строка означает заголовок, в нем может быть указано при помощи какого алгоритма выполняется хеширование подписи. Посередине — полезная информация, в ней может находиться username, id и/или роли пользователя, или что-то другое, что мы захотим добавить. А третья часть — это подпись, которая кодируется при помощи секретного ключа.
Каждая часть кодируется отдельно при помощи алгоритма base64url, соединяется через точку и хешируется при помощи алгоритма из заголовка, выглядит это так:
На официальном сайте, можно попробовать создать свой JWT. Если изменить хоть один символ в токене, то уже не пройдет проверку на соответствие на сервере.
Что нужно иметь в виду еще. Нужно на сервере обязательно проверять весь токен полностью, не только, условно, хедер. Например, прочитала в официальной брошюре-книге, что злоумышленник может указать в заголовке, что, мол, токен без подписи, пропускай мой запрос.
Поэтому, если мы хотим сохранить безопасность доступа, нужно проверять токен полностью, вместе с подписью, а также лучше делать его коротким по продолжительности жизни. В этом случае, как прочитала в комментариях у этой статьи про JWT на хабре, можно организовать автообновление токена с помощью oAuth2. До oAuth2 я еще пока не дошла, поэтому пока как на деле это сделать не знаю.
Как-то писала, что реализовывала Spring Security с дополнительным фильтром на JWT, но не написала, что такое JWT.
Хочу сегодня это исправить 👨💻 Для тех, кто не знает, надеюсь будет интересно, а кто знает, надеюсь, поправит меня, если я где-то ошибусь 😊
Итак, как вообще расшифровывается JWT? Расшифровывается, как JSON Web Token.
Как он выглядит?
Примерно, вот так (новые строчки добавлены для удобства чтения):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
Это своего рода закодированное сообщение. По условному разделению по строкам, верхняя строка означает заголовок, в нем может быть указано при помощи какого алгоритма выполняется хеширование подписи. Посередине — полезная информация, в ней может находиться username, id и/или роли пользователя, или что-то другое, что мы захотим добавить. А третья часть — это подпись, которая кодируется при помощи секретного ключа.
Каждая часть кодируется отдельно при помощи алгоритма base64url, соединяется через точку и хешируется при помощи алгоритма из заголовка, выглядит это так:
HMACSHA256(
base64UrlEncode(заголовок/header) + "." +
base64UrlEncode(полезная инфа/payload),
наш-256-битный-секрет
)
На официальном сайте, можно попробовать создать свой JWT. Если изменить хоть один символ в токене, то уже не пройдет проверку на соответствие на сервере.
Что нужно иметь в виду еще. Нужно на сервере обязательно проверять весь токен полностью, не только, условно, хедер. Например, прочитала в официальной брошюре-книге, что злоумышленник может указать в заголовке, что, мол, токен без подписи, пропускай мой запрос.
Поэтому, если мы хотим сохранить безопасность доступа, нужно проверять токен полностью, вместе с подписью, а также лучше делать его коротким по продолжительности жизни. В этом случае, как прочитала в комментариях у этой статьи про JWT на хабре, можно организовать автообновление токена с помощью oAuth2. До oAuth2 я еще пока не дошла, поэтому пока как на деле это сделать не знаю.
JSON Web Tokens - jwt.io
JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.
🔥4👍1
Всем привет!)
О мотивации пост.
Вчера пришла мысль, что меня очень мотивирует в изучении java и всего, что с ней связано (где-то о java говорят в мужском роде, мне почему-то хочется говорить в женском, надеюсь это вкусовщина, а не моя ошибка 😅).
Мысль меня посетила после лекции, которая закончилась уже вечером, а мне сильно захотелось заняться программированием и прямо так, чуть ли не всю ночь кодить. Задалась вопросом и поняла, что меня очень мотивируют крутые специалисты. Когда смотрю, как они программируют или рассказывают о чем-то в чем хорошо разбираются - это меня завораживает.
Один раз был смешной случай, как-то случайно по ссылке посмотрела час лекции по математике, там были сложные вычисления, что-то из продвинутого уровня, ничего не поняла, но не могла отвести взгляда)) после этого записалась на этот курс (бесплатный), но к сожалению не мой уровень.
Пыталась было с попроще видео на ютюбе зайти, но всё равно не вышло и решила не отвлекаться пока от программирования. Когда-нибудь возможно вернусь ещё)
А вас что мотивирует? 😊
О мотивации пост.
Вчера пришла мысль, что меня очень мотивирует в изучении java и всего, что с ней связано (где-то о java говорят в мужском роде, мне почему-то хочется говорить в женском, надеюсь это вкусовщина, а не моя ошибка 😅).
Мысль меня посетила после лекции, которая закончилась уже вечером, а мне сильно захотелось заняться программированием и прямо так, чуть ли не всю ночь кодить. Задалась вопросом и поняла, что меня очень мотивируют крутые специалисты. Когда смотрю, как они программируют или рассказывают о чем-то в чем хорошо разбираются - это меня завораживает.
Один раз был смешной случай, как-то случайно по ссылке посмотрела час лекции по математике, там были сложные вычисления, что-то из продвинутого уровня, ничего не поняла, но не могла отвести взгляда)) после этого записалась на этот курс (бесплатный), но к сожалению не мой уровень.
Пыталась было с попроще видео на ютюбе зайти, но всё равно не вышло и решила не отвлекаться пока от программирования. Когда-нибудь возможно вернусь ещё)
А вас что мотивирует? 😊
🔥5
Всем привет!
Хочу сегодня поделиться впечатлениями со стажировки. У нас выстраивается интересный большой проект. Пока там 4 сервиса, но модулей уже 6. Один модуль, dependency_bom, имеет в себе только pom.xml файл, в котором прописаны все зависимости в dependencyManagement и все версии этих зависимостей в properties.
Другой модуль содержит в себе чисто скрипты миграции для наполнения и откатывания разных изменений базы данных. Когда сама подключала Liquibase в своем проекте, сделала это по-другому, подключила в каждом модуле. Вариант с отдельным модулем понравился больше по удобству, так что возможно это отрефакторю в своём проекте тоже. Но пока там приоритет другой - настроить взаимодействие сервисов по OAuth2, но об этом попозже.
На стажировке нам нужно теперь прописывать работу с базой данных, и, что для меня новое, нужно будет в одном или нескольких сервисах использовать myBatis, вместо Hibernate.
MyBatis выглядит чуть сложнее в настройке с непривычки, хотя вроде он должен быть проще. Ему нужно прописывать связи и запросы в xml, либо использовать одну из последних версий, где добавили аннотации. Поизучаю, пока буду делать задание.
В целом, мне всё очень нравится, вижу много пользы для себя. Потом расскажу подробнее про свое изучение OAuth2, его пока только начала (читаю последние главы Spring Security in Action).
Хочу сегодня поделиться впечатлениями со стажировки. У нас выстраивается интересный большой проект. Пока там 4 сервиса, но модулей уже 6. Один модуль, dependency_bom, имеет в себе только pom.xml файл, в котором прописаны все зависимости в dependencyManagement и все версии этих зависимостей в properties.
Другой модуль содержит в себе чисто скрипты миграции для наполнения и откатывания разных изменений базы данных. Когда сама подключала Liquibase в своем проекте, сделала это по-другому, подключила в каждом модуле. Вариант с отдельным модулем понравился больше по удобству, так что возможно это отрефакторю в своём проекте тоже. Но пока там приоритет другой - настроить взаимодействие сервисов по OAuth2, но об этом попозже.
На стажировке нам нужно теперь прописывать работу с базой данных, и, что для меня новое, нужно будет в одном или нескольких сервисах использовать myBatis, вместо Hibernate.
MyBatis выглядит чуть сложнее в настройке с непривычки, хотя вроде он должен быть проще. Ему нужно прописывать связи и запросы в xml, либо использовать одну из последних версий, где добавили аннотации. Поизучаю, пока буду делать задание.
В целом, мне всё очень нравится, вижу много пользы для себя. Потом расскажу подробнее про свое изучение OAuth2, его пока только начала (читаю последние главы Spring Security in Action).
🔥10
Всем привет!
А знаете ли вы?
Что, оказывается, Hibernate не оптимизирует запросы, если ему дать запрос в native query. Вместо одного запроса с джоинами, он может сделать несколько запросов. Вчера опытным путем на это наткнулась.
А ещё оказалось, что если поставить @Lob над полем у сущности, с типом данных TEXT в базе данных, как в некоторых статьях советуют, Hibernate может ошибочно подумать, что это long и пытаться распарсить текст, как цифру, и выдавать ошибку DataIntegrityConflict.
Долго же я вчера искала почему хибернейт пытался подставить текст в идентификатор 😅 а оказалось дело было в @Lob.
Кстати, в книжке недавно прочитала такое наставление для новичков, сейчас уместно, как никогда об этом рассказать - "никогда не используйте в коде что-то, когда не знаете наверняка, что это делает и как работает" 😊
А знаете ли вы?
Что, оказывается, Hibernate не оптимизирует запросы, если ему дать запрос в native query. Вместо одного запроса с джоинами, он может сделать несколько запросов. Вчера опытным путем на это наткнулась.
А ещё оказалось, что если поставить @Lob над полем у сущности, с типом данных TEXT в базе данных, как в некоторых статьях советуют, Hibernate может ошибочно подумать, что это long и пытаться распарсить текст, как цифру, и выдавать ошибку DataIntegrityConflict.
Долго же я вчера искала почему хибернейт пытался подставить текст в идентификатор 😅 а оказалось дело было в @Lob.
Кстати, в книжке недавно прочитала такое наставление для новичков, сейчас уместно, как никогда об этом рассказать - "никогда не используйте в коде что-то, когда не знаете наверняка, что это делает и как работает" 😊
👍8